[{"title":"Elrond and NEAR","permalink":"https://goran.krampe.se/2021/04/21/elrond-and-near/","summary":"\u003cp\u003eBack in 2018 I got into crypto currencies. I ended up focusing on \u003ca href=\"http://nano.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNano\u003c/a\u003e\n and built \u003ca href=\"https://getcanoe.io\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eCanoe\u003c/a\u003e\n, a cross platform (mobile and desktop) wallet for Nano. Nano is \u003cstrong\u003ecrazy fast\u003c/strong\u003e (one or a few seconds) and has \u003cstrong\u003ezero fees\u003c/strong\u003e. For payments it\u0026rsquo;s superb and the architecture of Nano is clear and simple. I still have a lot of respect for Nano, but\u0026hellip; 2020 taught me one thing - smart contracts are actually not just a gimmick.\u003c/p\u003e\n\u003cp\u003eSo for me, sorry, Nano is not a project \u0026ldquo;of the future\u0026rdquo;!\u003c/p\u003e\n\u003cp\u003eI accidentally got involved in the DeFi world in the \u003ca href=\"https://cvault.finance\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eCORE\u003c/a\u003e\n project, which runs on top of Ethereum. My contribution was just making a cross Discord/Telegram chatbot, \u003ca href=\"https://github.com/gokr/robocore\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eRoboCORE\u003c/a\u003e\n, and writing a bit about \u0026ldquo;floor price calculations\u0026rdquo; but the whole DeFi landscape convinced me that smart contracts are \u003cstrong\u003ean essential ingredient in a modern crypto currency platform\u003c/strong\u003e.\u003c/p\u003e\n\u003cp\u003eReal true scalability is also mandatory, which IMHO really has to boil down to sharding, even if novel faster consensus models are damn cool like Avalance has (the Snowflake consensus protocol).\u003c/p\u003e\n\u003cp\u003eSo back to googling and reading \u0026hellip; and there are two projects that so far stand out in my book:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://elrond.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eElrond\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://near.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNEAR protocol\u003c/a\u003e\n\u003c/li\u003e\n\u003c/ul\u003e","content":"Back in 2018 I got into crypto currencies. I ended up focusing on Nano and built Canoe , a cross platform (mobile and desktop) wallet for Nano. Nano is crazy fast (one or a few seconds) and has zero fees. For payments it\u0026rsquo;s superb and the architecture of Nano is clear and simple. I still have a lot of respect for Nano, but\u0026hellip; 2020 taught me one thing - smart contracts are actually not just a gimmick.\nSo for me, sorry, Nano is not a project \u0026ldquo;of the future\u0026rdquo;!\nI accidentally got involved in the DeFi world in the CORE project, which runs on top of Ethereum. My contribution was just making a cross Discord/Telegram chatbot, RoboCORE , and writing a bit about \u0026ldquo;floor price calculations\u0026rdquo; but the whole DeFi landscape convinced me that smart contracts are an essential ingredient in a modern crypto currency platform.\nReal true scalability is also mandatory, which IMHO really has to boil down to sharding, even if novel faster consensus models are damn cool like Avalance has (the Snowflake consensus protocol).\nSo back to googling and reading \u0026hellip; and there are two projects that so far stand out in my book:\nElrond NEAR protocol \u0026hellip;ok, so there are tons of so called \u0026ldquo;eth killers\u0026rdquo; out there. I have looked at least a little bit on most of them by now.\nElrond Link to heading I find Elrond to be one of the most promising. Strong solid development focus, just like Nano always had. But also good marketing which Nano sucked at, yup, it\u0026rsquo;s the truth. Sub second transactions? No, but Elrond does them in 5-6 seconds which is just below the magical threshold in order to be useful for payments.\nZero fees? No, not zero, but very very low. And while Nano\u0026rsquo;s idea of using a bit of PoW as payment is pretty neat, it still suffers from the \u0026ldquo;spam problem\u0026rdquo; (although recent developments may have solved it, unsure), so a low fee is probably a smarter more practical route to take. Elrond can also shift the fee to a third party so that end users can use a system feeless, that\u0026rsquo;s clever and very useful.\nThe Elrond team is primarily in Romania but seems to be doing a great job in maintaining a good community. They also realize that the end users are key - so they also made Maiar which was relatively recently released. It\u0026rsquo;s a very slick and smooth mobile wallet for EGLD (eGold) which also maps phone numbers and so called \u0026ldquo;herotags\u0026rdquo; to accounts. That last part is a brilliant move by the Elrond team.\nWhen we made Canoe for Nano we also implemented a system for \u0026ldquo;aliases\u0026rdquo; (like herotags, we even used \u0026ldquo;@\u0026rdquo; as prefix) but\u0026hellip; since it was not \u0026ldquo;on chain\u0026rdquo; it suffered from fragmentation with several different implementations and security risks in abundance. So putting this on chain is really the ONLY solution, and it is a true enabler.\nMaiar takes your phone number, hashes it and then associates the hash with the Elrond account of your wallet, and stores it on chain. Net effect is that as Maiar (or other Elrond wallets) virally spreads to more people - you will be able to see which of your existing contacts in your phone already has an Elrond account and can be sent EGLD. Very nice indeed. At the same time, the phone number is not revealed, since it\u0026rsquo;s a hash being stored.\nElrond seems to have a very good base with a properly sharded design up and running on mainnet and several pieces being put in place. It also made a true run in value early 2021, from about $25 and quickly up over $210. It\u0026rsquo;s probably a good bet it will continue climbing, but hey, not financial advice of course ;)\nNEAR Protocol Link to heading Another contender in the ethereum killer space is the NEAR protocol. It\u0026rsquo;s a technically very capable project that has a more \u0026ldquo;grassroot, down to earth\u0026rdquo; feeling. Not as much marketing as Elrond, which to be honest sometimes gets a bit over the top for my taste. I mean, how many meaningful \u0026ldquo;partnerships\u0026rdquo; can a project really have?\nNEAR has that \u0026ldquo;community feeling\u0026rdquo; that I like a lot, even the website is a .org and not a .com. No nonsense, tech first, developers first. And technically it might be one of the strongest projects around, even Vitalik Buterin has acknowledged that NEAR may present itself as a worthy challenger to Ethereum 2. Very fast finality, a solid sharded design. And to be frank, I love the website style with documentation and developer focus!\nI haven\u0026rsquo;t dwelved that deeply into NEAR yet, but they also have a clever DNS based account naming model similar to EGLD. And no, there is no official mobile wallet (there are other multi currency wallets supporting NEAR), but\u0026hellip; in some ways it may be a strategy more in line with the grassroot model of NEAR. NEAR focuses on the platform and might be better off leaving things like mobile wallets to external parties.\nConclusion Link to heading There are lots and lots of new smart contract platforms out there vying for a bit of the \u0026ldquo;Ethereum cake\u0026rdquo;. Will Ethereum 2 deliver and make all other obsolete? Will the future have room for 10 or 20 different platforms? Or will 2-3 of these new kids on the block (sorry for the pun) step up and take over?\nI have no clue but it seems to me that:\nEthereum is struggling now due to insane gas costs, projects are scrambling for alternatives. Ethereum 2 seems too far in the future before it starts being useful. Elrond and NEAR are two of the most interesting competitors, and they are working right now. Elrond is at the time of writing at $3,315,197,861 in market cap with 55% in circulation. NEAR is at $1,770,738,752 with 36% in circulation. Elrond is 84x smaller market cap that current Ethereum.\nOk, so sorry, this article doesn\u0026rsquo;t go into that much technical details. You will just have to learn yourself!\nAnd no, nothing of the above is financial advice. ;)\n"},{"title":"Spry Error Handling","permalink":"https://goran.krampe.se/2021/04/21/spry-error-handling/","summary":"\u003cp\u003eWork on \u003ca href=\"https://sprylang.se\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSpry\u003c/a\u003e\n continues\u0026hellip; in small spurts. :) One thing that I have pushed ahead of me for far too long is \u003cstrong\u003eerror handling\u003c/strong\u003e. People interested in Spry have been asking about it and yes, I decided to start getting a handle on it.\u003c/p\u003e\n\u003cp\u003eIn fact, I wrote this article \u003cstrong\u003elast year\u003c/strong\u003e but forgot to get it done and published!\u003c/p\u003e\n\u003cp\u003eError handling is an interesting topic, earlier it wasn\u0026rsquo;t really much controversy around it but the advent of new techniques (Optionals etc) in combination with languages making\u0026hellip; \u0026ldquo;interesting\u0026rdquo; choices (I am looking at you Go) has made this subject fairly hot. So what do we want in Spry??\u003c/p\u003e","content":"Work on Spry continues\u0026hellip; in small spurts. :) One thing that I have pushed ahead of me for far too long is error handling. People interested in Spry have been asking about it and yes, I decided to start getting a handle on it.\nIn fact, I wrote this article last year but forgot to get it done and published!\nError handling is an interesting topic, earlier it wasn\u0026rsquo;t really much controversy around it but the advent of new techniques (Optionals etc) in combination with languages making\u0026hellip; \u0026ldquo;interesting\u0026rdquo; choices (I am looking at you Go) has made this subject fairly hot. So what do we want in Spry??\nError handling Link to heading Exceptions, errors etc are simply \u0026ldquo;not so often expected paths of execution\u0026rdquo;. Clarity of code can often be enhanced if the vanilla code path is clean of clutter for all these less expected paths. One common mechanism to achive this in some form is of course the try-catch style of Exeption handling.\nI want most Spry code to be uncluttered. I also don\u0026rsquo;t want too many concepts in the language since Spry is meant to be minimalistic in nature.\nOne thing has already been added, I call it the catch-throw mechanism. The idea is to have it as a base for most of the rest of the call stack based mechanisms. For even more advanced stack manipulations the stack is gradually being reified, but that will be explored more when making the first Spry debugger.\nThere are quite a few ideas in current languages on error handling:\nReturn errors just like values from the called function. Throw errors and catch them at an appropriate level higher up the stack, thus avoiding boilerplate for just passing them along. Also avoids the issue with code expecting a proper result suddenly getting an error in their hands. Multiple return so that a function can return both a value and a potential error, often exclusive. Optionals, the idea of stuffing an error and a value into a \u0026ldquo;struct\u0026rdquo; so that we still return \u0026ldquo;just a single thing\u0026rdquo;, but it can contain either a proper value, or an error. defer and errdefer, the idea of installing a handler that can do cleanups, either always before returning or only before returning with an error etc. Declarations showing the developer if a function can return errors, and potentially exactly what errors it can return. Rebol treats errors as a specific kind of fundamental value type, but several languages treat errors as values (Go etc). Rebol uses a \u0026ldquo;bomb\u0026rdquo; trick so that it can return either a proper value, or an error (that will blow up if evaluated). Smalltalk and Dylan (and perhaps CLOS) has a conditional throw-catch system which means the stack is not unwound when the search for a handler is performed. This means resume after the throw is possible. Erlang has the idea of simply not trying to recover from errors, just restart instead. It\u0026rsquo;s a nice idea. Smalltalk uses blocks pervasively in control structures and also in exceptional handling like for example with at:ifAbsent: etc. Also found a nice article discussing some of the above.\nCatch throw Link to heading In Spry we now have a basic catch-throw mechanism in place, and that is useful for making calls to handlers \u0026ldquo;up the stack\u0026rdquo;, not just errors. I started with the STTCPW , so\u0026hellip; added a slot in the Activation record called \u0026ldquo;catcher\u0026rdquo;. Setting this slot to a code block/func installs a \u0026ldquo;guard\u0026rdquo; that will be invoked if a throw is performed inside this activation, or in an activation below. This was simple to implement and acts as a reasonable primitive for error handling.\nSo\u0026hellip; this example works in ispry:\nfoo = func [ activation catcher: [echo (\u0026quot;Caught a \u0026quot;, :banana)] echo \u0026quot;Throwing a banana...\u0026quot; throw \u0026quot;banana\u0026quot; ] foo \u0026hellip;will print:\nThrowing a banana... Caught a banana If an activation record does not have a handler, throw will keep searching upwards and if none is found it will currently do a hard process exit 1.\nTypically though, the top activation record should have a catch all handler installed and do something reasonable.\nAs in Smalltalk (and some other languages) throwing an Exception does not unwind the call stack, so a handler doing a normal return will return back to the throw! Unless it calls activation unwind first, if so, the return will instead go to caller of the record where the handler is installed (NOT YET IMPLEMENTED). In fact, the principle of least surprise may mean we should swap these behaviors :)\nWith this in place we can implement catch: (resembling try/catch) like:\ncatch: = method [activation catcher: :handler do self] \u0026hellip;so what does this do? It\u0026rsquo;s a method, so it takes a receiver block on the left. When we run the method we are in a new Activation, and we set the catcher to the given handler block passed as the argument, and then we do self in order to execute the receiver block that may possibly throw.\nThis enables \u0026ldquo;scoped\u0026rdquo; use familiar from most languages. Below we see it in action:\nfoo = func [ # This is an activation level catcher, just to show we never reach it activation catcher: [echo \u0026quot;we never reach this\u0026quot;] # Here we call `catch:` on a block with a handler block as argument. # This is the classic try-catch style found in many languages. [ echo \u0026quot;Throwing a banana...\u0026quot; throw \u0026quot;banana\u0026quot; ] catch: [ echo (\u0026quot;Caught a \u0026quot;, :banana) ] ] foo \u0026hellip;and it should print the same as before and never reach the catcher in foo :)\nGoing back to the general problem of error handling, my feelings so far:\nGo style multiple return and tons of if err != nil {...} is NOT to my liking. I can understand the philosophy, but sorry, don\u0026rsquo;t like it. Especially not in the minimalistic style that Spry tries to adhere to. Only a try-catch conditional system like Smalltalk has is kinda boring. It can also get fairly confusing to debug, for example try-catch with empty catch clauses that \u0026ldquo;swallows\u0026rdquo; errors in silence, nested calls get hairy. It can also blur the \u0026ldquo;vanilla case\u0026rdquo; quite a lot. Nevertheless, it may form a \u0026ldquo;base\u0026rdquo; in combination with other mechanisms. It would be fun with something simpler and different! Spry is an experiment! But not sure yet what this would be\u0026hellip; Spry shares the evaluation model of Rebol (kinda-ish), so the idea Rebol has with a special \u0026ldquo;bomb\u0026rdquo; is tempting in its simplicity, especially when writing vanilla code to begin with! Spry has tagging, we should be able to use it somehow, for example to tag funcs and methods. I want to be able to write vanilla code as long as possible, then gradually hardening, for example as result of unit tests. But I don\u0026rsquo;t want hardening to introduce clutter in the vanilla code! Thus, somehow, I would want to be able to add error handling as a \u0026ldquo;side track\u0026rdquo; and not inlined in the vanilla code. The idea of doing error handling \u0026ldquo;on the side\u0026rdquo; and not inlined in the vanilla code. Defer and errdefer are going in this direction, they are code blocks that are executed only if certain rules are met, but they are clearly separate. We can either throw, or return. But we could also \u0026ldquo;signal\u0026rdquo;. A signal is a neutral way of signalling a condition, it does not imply what to do next, we could hard exit the process :), or we could always log it and then throw, or we could always return it as a bomb etc. Dylan has interesting features, perhaps worth reading closely: https://opendylan.org/documentation/intro-dylan/conditions.html and https://opendylan.org/books/drm/Conditions_Background So\u0026hellip; where to go from here? Ideas?\nregards, Göran\n"},{"title":"CORE floor price musings","permalink":"https://goran.krampe.se/2020/11/01/floor-price-musings/","summary":"\u003cp\u003eI have already written \u003ca href=\"http://goran.krampe.se/categories/core\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ethree different articles\u003c/a\u003e\n explaining how CORE floor price can be calculated. But just a day or two back the CORE team decided that using the floor price concept in communcation doesn\u0026rsquo;t work out very well. Why? Because a LOT of people just can\u0026rsquo;t seem to understand it properly and keep perpetuating wrong conclusions around it. In short - people can\u0026rsquo;t understand math :)\u003c/p\u003e\n\u003cp\u003eA list of common misconceptions are:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eFloor price is the \u0026ldquo;correct value\u0026rdquo; of CORE and that the current price then must be too high\u003c/li\u003e\n\u003cli\u003eFloor price is some kind of approximation and the price can actually go lower\u003c/li\u003e\n\u003cli\u003eFloor price is a technical analysis support level\u003c/li\u003e\n\u003cli\u003eFloor price can change if another market starts trading CORE lower\u003c/li\u003e\n\u003cli\u003eFloor price can never ever go down in USD value\u003c/li\u003e\n\u003cli\u003eFloor price can never ever go down in ETH value\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eAnd a whole bucket of other misconceptions - just pile it on! Let us start with an explanation of what floor price \u003cstrong\u003eACTUALLY IS\u003c/strong\u003e and then go through the above list\u0026hellip;\u003c/p\u003e","content":"I have already written three different articles explaining how CORE floor price can be calculated. But just a day or two back the CORE team decided that using the floor price concept in communcation doesn\u0026rsquo;t work out very well. Why? Because a LOT of people just can\u0026rsquo;t seem to understand it properly and keep perpetuating wrong conclusions around it. In short - people can\u0026rsquo;t understand math :)\nA list of common misconceptions are:\nFloor price is the \u0026ldquo;correct value\u0026rdquo; of CORE and that the current price then must be too high Floor price is some kind of approximation and the price can actually go lower Floor price is a technical analysis support level Floor price can change if another market starts trading CORE lower Floor price can never ever go down in USD value Floor price can never ever go down in ETH value And a whole bucket of other misconceptions - just pile it on! Let us start with an explanation of what floor price ACTUALLY IS and then go through the above list\u0026hellip;\nThe floor price is a technical mathematical price that CORE can never ever go below as long as:\nThere are only 10000 CORE. And that\u0026rsquo;s in the design of CORE, so can not change. Uniswap pricing mechanism isn\u0026rsquo;t changed. That\u0026rsquo;s in the Uniswap v2 contract so can also not change. The CORE contracts forbid liquidity tokens to be converted back to the underlying assets. In other words, you can not remove liquidity from a Uniswap CORE trading pair after you have added it. These three pillars were listed in my first article, but I list them here again. These three facts work together to create the price floor.\nOk, so\u0026hellip; first of all - if we could mint more CORE, then of course price would go lower. If you suddenly double the supply of COREs the price would promptly go to half. So a fixed supply is very important. Secondly, the insight that the price on Uniswap is not a price set by the \u0026ldquo;sellers\u0026rdquo;, it\u0026rsquo;s not governed by any human at all, it\u0026rsquo;s just governed by math. There are tons of articles on how this works and my first article did explain it carefully.\nHow does the price go down in the first place? If people don\u0026rsquo;t want to hold CORE and decide to sell it, then price goes down. Let\u0026rsquo;s pretend the CORE holder world consists of Lisa, Peter and John. They all have 1000 CORE each. The rest is in the Uniswap trading pairs. If Lisa decides to sell all her CORE it will end up inside one of the pairs, and she will get ETH or CBTC in return. The price of CORE goes down (Uniswap math, pillar two), as well as the pile of ETH (or CBTC) in the pair she sold into (Uniswap math, pillar two), since she got ETH (or CBTC) in return.\nIf John and Peter also sells all their CORE then all CORE is suddenly in the trading pairs. No CORE is held by any other party. Since there is no more CORE, remember - we can\u0026rsquo;t mint more CORE, then there is no more CORE to sell into the pairs. The maximum of CORE that can be in the pairs, is thus 10000. See pillar one above.\nAt this point, is there ETH and CBTC still left inside the pairs? Yes there is! The sum of all that ETH and CBTC is what we like to call the TVPL - Total Value Permanently Locked. The word \u0026ldquo;permanently\u0026rdquo; here implies that this big chunk of value can never ever be removed from the pairs, because the only way to \u0026ldquo;get\u0026rdquo; that ETH and CBTC is to sell CORE into the pair, but there is no more CORE to sell!\nOk, but what if \u0026hellip; the people who provided the liquidity into the pairs in the first place came and removed it? Ah. Right. They can\u0026rsquo;t. That\u0026rsquo;s the third pillar above. The contracts of CORE have that distinguishing feature - that once you added liquidity and got a Liquidity Pool token in return - then you can\u0026rsquo;t reverse it.\nI hope it\u0026rsquo;s clear at this point that if all CORE is sold, we would end up at the lowest price. The fun part is that this price can be calculated, because Uniswap has such a clean mathematical pricing formula. It\u0026rsquo;s not governed by supply and demand - it\u0026rsquo;s governed by simple plain math.\nNow\u0026hellip; let\u0026rsquo;s take a look at all misconceptions.\nFloor price is the \u0026ldquo;correct value\u0026rdquo; of CORE and the current price must be too high Link to heading There is no human involved in \u0026ldquo;deciding\u0026rdquo; or \u0026ldquo;setting\u0026rdquo; the floor price, it\u0026rsquo;s just a mathematical boundary. But the value of CORE is up to us to decide, that depends on expectations going forward and so on, just like the value of a stock or some other valuable. The only reason CORE to actually ever get anywhere close to the floor price would be a total freaking disaster in the CORE eco system, making everyone feel that CORE is simply worthless! And everyone would decide to panic sell. I guess one could say that other clones of CORE have \u0026ldquo;tested the floor price concept\u0026rdquo;, by failing miserably to deliver on promises and thus people have decided that hey, this is a worthless clone - and sold. But yes, even in such a disaster - the price simply can\u0026rsquo;t go to zero.\nAn analogy would be if we could go to a vault, and put in 1 ETH, and get an IOU-note back. And at any point in time I can go back to the vault and exchange that IOU back to the 1 ETH. Now\u0026hellip; I can sell that IOU to you, but I would be daft if I sold it for 0.5 ETH, because you can always go and exchange it for 1 ETH. So \u0026hellip; in a similar way CORE also has this base value locked away, the TVPL, so that you can always sell your CORE for at least the floor price - around $633 at the time of writing.\nBut CORE is a project, en endeavour, with plans going forward and a team and community delivering on the plans. Thus it has a promise of future earnings and that is what drives the current price. The floor is of course an interesting factor in all this, the fact that there even is a floor is a strength of CORE.\nFloor price is some kind of approximation and the price can actually go lower because anything can go to zero value Link to heading No. There is no human that has made any kind of estimation or valuation here. The floor price is just a mathematical truth. But sure, it does depend on certain factors - like we need the Internet to keep working and the Ethereum blockchain must still work, since the CORE ecosystem is built on Ethereum smart contracts.\nThe dependence on Uniswap is quite small and could relatively easily be replaced. But yes, if World War III kills the Internet - then CORE is quite worthless. But so would lots of other currencies be at that point.\nFloor price is a technical analysis support level Link to heading No, no, no. A support level is just an imaginary construct - it\u0026rsquo;s a \u0026ldquo;level\u0026rdquo; we humans see when we study a chart. We notice perhaps that an asset tends to stay above a certain price over a period of time, and then one of us decides to call that a \u0026ldquo;support level\u0026rdquo;. Technical analysis has nothing to do with the floor price.\nI am trying to lose some weight, I have been hovering around 88 kg but I want to get down to 83. Evidently there is some kind of \u0026ldquo;support level\u0026rdquo; around 88 kg :) but\u0026hellip; depending on choice of mathematical models I could argue with decent certainty that floor mass for me is 12.5 kg. I promise that it\u0026rsquo;s impossible for me to have less mass than that, because that is the mass of my skeleton. Ok, so first draft of this article I claimed floor mass to be 0, but it felt a bit silly. The clever reader noticed me choosing the word \u0026ldquo;mass\u0026rdquo; instead of \u0026ldquo;weight\u0026rdquo; since I actually do weigh 0 kg in space, but my mass is for sure more than 12.5 kg. Perhaps not the best analogy to pick!\nFloor price can change if another market starts trading CORE lower Link to heading This is interesting though. There are already other markets for CORE than the two trading pairs on Uniswap. Hotbit and Gate are two CEXes evidently offering trading in CORE, but they all currently trade at a slightly higher price than on Uniswap. Those markets follow supply and demand, using an order book, so don\u0026rsquo;t play by the same rules so to speak. But arbitrage ought to work in the direction of making the price similar. But remember - floor price is the ultimate disaster scenario. What would happen? Noone would want to buy CORE on those CEXes in such a panic sell off, so all sellers would flock back to the trusty Uniswap because Uniswap always buys from you! So all CORE would still flow right back into the AMM pairs, and we would still hit the same old floor. So other non AMM markets have no real impact on the floor price, at least to my current understanding.\nBut any new AMM pairs using Uniswap pricing model definitely impacts the floor price! When the next third pair is launched the floor price will take yet another jump upwards. And if any of the already existing CORE pairs on Uniswap suddenly starts getting liquidity - they would impact floor too.\nFloor price can never ever go down in USD value Link to heading Oh yes it can! When we had a single CORE-ETH pair then the floor was around 1.13 ETH. It could never go below 1.13 ETH. But the price of ETH in USD varies, so if we looked at the floor price in USD - then sure, it varied over time just as much as ETH varied!\nBut now we also have a second pair in CBTC. So the current floor price is actually part ETH and part BTC. This means the current floor price, which is around 1.66 ETH (it took a healthy jump from around 1.13 to 1.6 ETH when second pair was introduced) - should in theory actually be more stable, since one can argue that a portfolio consisting of part ETH and part BTC will have a more stable or balanced total value, than if it was only ETH or only BTC.\nSo it can go down in USD. But this movement is exactly the same as the movement of ETH and BTC.\nFloor price can never ever go down in ETH value Link to heading That was true, when we had just the CORE-ETH pair. Now it\u0026rsquo;s not true anymore, because the floor value is part BTC also, so if BTC drops in value compared to ETH, then the total floor valued in ETH would go down. Similarly, if we valued it in BTC it could go down if ETH went down, in relation to BTC. Argh! :) But it\u0026rsquo;s not a negative, on the contrary. The current mix of the floor value makes it more resistant to movements. And with the third DAI pair coming, it will be even more stable.\nAll of this is just per my own understanding of the concepts involved and should DEFINITELY NOT be taken as any kind of financial advice :) But if you ask me - the floor price is a great thing and it makes CORE quite unique. It\u0026rsquo;s the solid bed rock underneath the house. We don\u0026rsquo;t want to sleep directly on it, but we sure like it\u0026rsquo;s there to keep the house steady.\nFinally, here is a trivial floor.ods spreadsheet where you can experiment with new pairs. By estimating amount of CORE in the existing and any new pairs the spreadsheet shows the new floor price.\nCheers, Göran\n"},{"title":"CORE floor price over more pairs","permalink":"https://goran.krampe.se/2020/10/29/floor-price-revisited/","summary":"\u003cp\u003eIn the previous article I explained the principles behind CORE\u0026rsquo;s floor price, the lowest price that CORE can reach. It\u0026rsquo;s a novel concept and a very interesting characteristic of CORE.\u003c/p\u003e\n\u003cp\u003eI showed the mechanisms involved and how to calculate the floor price, if we only have \u003cstrong\u003ea single\u003c/strong\u003e \u003ca href=\"https://info.uniswap.org/pair/0x32ce7e48debdccbfe0cd037cc89526e4382cb81b\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003etrading pair\u003c/a\u003e\n to worry about. I have also solved the equation for two trading pairs, that equation is currently used in RoboCORE with success.\u003c/p\u003e\n\u003cp\u003eBut how to handle three pairs or more? Complexity seemed to spin out of control, but\u0026hellip; it turns out \u003cstrong\u003ethere is a simple solution!\u003c/strong\u003e\u003c/p\u003e","content":"In the previous article I explained the principles behind CORE\u0026rsquo;s floor price, the lowest price that CORE can reach. It\u0026rsquo;s a novel concept and a very interesting characteristic of CORE.\nI showed the mechanisms involved and how to calculate the floor price, if we only have a single trading pair to worry about. I have also solved the equation for two trading pairs, that equation is currently used in RoboCORE with success.\nBut how to handle three pairs or more? Complexity seemed to spin out of control, but\u0026hellip; it turns out there is a simple solution!\n\u0026hellip;but before we get to the beautiful simple solution that works for n number of pairs, we need to really bask ourselves in the glory of complexity in solving it for two pairs using the obvious math used from the solution for one pair.\nWithout explaining the math too carefully (sorry), the equations from one pair suddenly got a bit more complex. Let\u0026rsquo;s presume we are going to sell X COREs back into pair1, and the rest into pair2 - and afterwards the two pairs should have the same price, which will be the floor price.\nFor pair one we can formulate the new amount of ETH in the pool as newPoolETH = k / (poolCORE + (X * 0.997)) taking the Uniswap fee into account. And using the fact that the rest needs to get sold into pair2, we then get newPoolWBTC = k2 / (poolCORE2 + (10000 - poolCORE2 - poolCORE - X) * 0.997).\nAfter these two trades are done the price of both pools should be equal to each other. The two price formulas are price1 = newPoolETH / (poolCORE + X) and price2 = (newPoolWBTC / (10000 - poolCORE - X)) * priceBTCinETH. So let\u0026rsquo;s put them equal to each other:\nnewPoolETH / (poolCORE + X) = (newPoolWBTC / (10000 - poolCORE - X)) * priceBTCinETH \u0026hellip;and we can expand newPoolETH and newPoolWBTC from the previous equations giving us this final big one:\n(k / (poolCORE + (X * 0.997))) / (poolCORE + X) = (k2 / (poolCORE2 + (10000 - poolCORE2 - poolCORE - X) * 0.997)) / (10000 - poolCORE - X) * priceBTCinETH As a careful reader now notices we have only one unknown in the equation, and that is X! Yes! So we need to solve for X. And\u0026hellip; that\u0026rsquo;s where it get\u0026rsquo;s really messy! I am not going further here, but let\u0026rsquo;s just conclude that it can be done and that it turns into a second order equation with two potential solutions for X. Often we can ignore one of the solutions as impossible in practice. This math is currently used by RoboCORE and it calculates the floor price exactly for the two current CORE pairs we have.\nA Simple Beautiful Solution Link to heading Someone came up with the idea on Discord or Telegram (don\u0026rsquo;t recall which one) that\u0026hellip; perhaps all the pairs could be combined into a single pair, and thus the problem would be trivial even for many, many pairs? It sounded nice, but instinctively I felt that the \u0026ldquo;k constant\u0026rdquo; would sort of get lost in such a way of thinking.\nBut it was intriguing to find a solution for n number of pairs (since the third pair is probably juuuuust around the corner) so I started playing around in LibreOffice Calc. After an hour of juggling numbers and mainly goofing around it dawned upon me that\u0026hellip; there is a solution that is so simple it\u0026rsquo;s almost \u0026hellip; unbelievable!\nThe Assumption Link to heading Let\u0026rsquo;s pretend we have n pairs. The problem we need to solve is still how to distribute the remainder of CORE outside of the pairs into the n pairs so that they all end up having the same price (in ETH for example, or USD). There is an assumption we can make that can be used to make this much simpler and that is presuming that the pairs have the same price already. At least within say 1-2% or whatever small margin we allow. If they wouldn\u0026rsquo;t, then someone would arbitrage and make them get close again. So the assumption seems fine!\nAha! So the problem suddenly is easier. We just need to distribute our CORE so that we change the price with the same factor for all the pairs. Because if they already are the same price, and we change the price with the same factor, then they damn well ought to still be the same after we have poured our last COREs into them!\nOk, how was the price formulated for a pair now again? The current price is just poolCORE / poolZZZ (where ZZZ is ETH or CBTC at the moment, depending on pair). Ok, that is not helpful because the new price depends on the amount of CORE we sell into the pair. So, we need to figure out how much CORE to sell into each pair, to make sure the price is changed with the same factor.\nLet us recall the Uniswap math from above for price1. It\u0026rsquo;s the left side of the long equation above:\nprice = (k / (poolCORE + (X * 0.997))) / (poolCORE + X) This is the price of a pair after we have added X amount of CORE to it. Note that it only depends on k and poolCORE! The different pairs will have different k. Hmmm, ok. For simplicity, let\u0026rsquo;s rename poolCORE to just C for CORE.\nLet us rewrite that expression to: price = k / ((C + 0.997 * X)(C + X))\nAnd X\u0026hellip; let\u0026rsquo;s pretend X = q * C, or in other words, we will add a number of CORE that is proportional to the number of CORE already in the pair - the proportion we call q. So if pair has 100 CORE and q is 0.5, then we will add 50 CORE for that pair. Now we can rewrite the formula for price once more, replacing X with q * C so it now looks like:\nprice = k / ((C + qC * 0.997)(C + qC)) \u0026hellip;and we can then extract C from the expression so that it now looks like:\nprice = k / (C^2 * (1 + 0.997q)(1 + q)) At this point you are staring blankly at the screen thinking\u0026hellip; he\u0026rsquo;s gone mad! The mad hatter! :) Let\u0026rsquo;s take a look and see what the heck we have arrived at.\nThe formula says that the new price for any of the pairs will be it\u0026rsquo;s k divided by C^2 (the amount of CORE in the pair) multiplied with \u0026ldquo;an expression of q\u0026rdquo;. And q was a proportion of the existing CORE in the pair. Uhuh.\nSo\u0026hellip; if we can use the same q for all our pairs, then \u0026hellip; the price of all our pairs will be divided by the same number, namely (1 + 0.997q)(1 + q). And since their price were the same before, then dividing by the same number will make them all the same again!\nMuuhhaaahahaa! \u0026hellip;insert Evil laughter and Mad Hatter eyes glistening here\u0026hellip; we are close now! So we just need to find a q that makes sure we put all our \u0026ldquo;outside\u0026rdquo; CORE into the pairs.\nLet\u0026rsquo;s grab an example! Let\u0026rsquo;s say we have 5 pairs and they have 200, 3000, 250, 600 and 850 COREs each. This makes a total of 4900 COREs and that means we have 5100 COREs free \u0026ldquo;outside\u0026rdquo; of the pairs. Now.. we just need a q to consume all 5100 COREs!\nSo 5100 = q*200 + q*3000 + q*250 + q*850 which is 5100 = q(200 + 3000 + 250 + 850) and yes, q = 5100 / (200 + 3000 + 250 + 850). Bam! We have q and thus we can trivially calculate the new price of ANY pair, and funny enough - we only need to calculate the new price for ONE pair, because all will have the same price!\nYeah, right, he has lost his last marble Link to heading You are thinking\u0026hellip; he is just blowing smoke up our\u0026hellip; something. Let us apply the above to the current two pairs! I asked RoboCORE at the time of writing and he said the CORE-ETH pair has 3471 CORE \u0026amp; 33349 ETH, and the CORE-CBTC pair has 638 CORE \u0026amp; 179 CBTC.\nThis gives price1 = 33349 / 3471 = 9.60789 ETH * 388.80 = $3735 and price2 = 179 / 638 = 0.28056 BTC * 13761.76 = $3861. Hmmm, oops, diff of almost 3% but yeah, let\u0026rsquo;s pretend they are the same! :)\nNow\u0026hellip; Robo says floor price is 1.6325 ETH. Can we find the same number using the q approach?\nSo we find q using q = (10000 - 3471 - 638 - 1280) / (3471 + 638 + 1280) = 1.43368216111. We then take q * 3471 = 4976.3 CORE and add it to pair1 and we add the rest (5891 - 4976.3) to pair2, which should also be same as q * 638 = 914.7 (yup it is). Now, the new price of pair1 should be (k / (poolCORE + (X * 0.997))) / (poolCORE + X) so price = (3471 * 33349) / (3471 + 0.997 * 4976.3)(3471 + 4976.3). And it yields 1.625 ETH! Close enough!\nLet\u0026rsquo;s look at pair2, it should end up at the same price: price = (638 * 179) / (638 + 0.997 * 914.7)(638 + 914.7). It\u0026rsquo;s 0.04745334321! Eh.. what the hell? Oh, in BTC :) So \u0026hellip; multiply by price of WBTC in ETH which is 34.22899 and we have 1.6243 ETH!\nAnd that\u0026rsquo;s where I say \u0026hellip; Yippee ki-yay muth\u0026hellip; I mean, Yippee ki-yay!\n"},{"title":"CORE floor price short howto","permalink":"https://goran.krampe.se/2020/10/29/floor-price-short-howto/","summary":"\u003cp\u003eIn the previous \u003ca href=\"http://goran.krampe.se/2020/10/29/floor-price-revisited/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003etwo\u003c/a\u003e\n \u003ca href=\"http://goran.krampe.se/2020/10/28/floor-price-in-core/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003earticles\u003c/a\u003e\n I explained the principles behind CORE\u0026rsquo;s floor price, the lowest price that CORE can reach and ended it all by explaining the \u0026ldquo;q method\u0026rdquo; that works for any number of CORE pairs. For lots of people that was possibly an overdose of math, so \u0026hellip; here is the super short and \u003cstrong\u003elacking any explanations on why\u003c/strong\u003e description on how to calculate floor price of CORE using the \u0026ldquo;q method\u0026rdquo;.\u003c/p\u003e","content":"In the previous two articles I explained the principles behind CORE\u0026rsquo;s floor price, the lowest price that CORE can reach and ended it all by explaining the \u0026ldquo;q method\u0026rdquo; that works for any number of CORE pairs. For lots of people that was possibly an overdose of math, so \u0026hellip; here is the super short and lacking any explanations on why description on how to calculate floor price of CORE using the \u0026ldquo;q method\u0026rdquo;.\nFind q. This is done by:\nq = (10000 - sum-of-all-CORE-in-all-pairs) / (sum-of-all-CORE-in-all-pairs) Then take one pair, for example the CORE-ETH pair, and calculate floor as:\nfloor = (poolCORE * poolETH) / ((poolCORE + 0.997 * (q * poolCORE)) * (poolCORE + q * poolCORE)) And that\u0026rsquo;s it, so again, using the numbers at the time of writing (ask RoboCORE with command !s in Discord or /s in Telegram):\nq = (10000 - (3451 + 630)) / (3451 + 630) = 1.45037980887 And then:\nfloor = (3451 * 33578) / ((3451 + 0.997 * (1.45037980887 * 3451)) * (3451 + 1.45037980887 * 3451)) = 1.62336028634 At this moment RoboCORE says floor is 1.6228 so yeah, 1.62336028634 is close enough!\nCheers, Göran\n"},{"title":"Everything you wanted to know about CORE floor price but was too afraid to ask","permalink":"https://goran.krampe.se/2020/10/28/floor-price-in-core/","summary":"\u003cp\u003eThe last month I have gotten involved in a fairly new crypto currency project called \u003ca href=\"https://twitter.com/CORE_Vault\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eCORE\u003c/a\u003e\n, or \u003ca href=\"https://cvault.finance\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ecvault.finance\u003c/a\u003e\n. My main contribution is \u003ca href=\"https://github.com/gokr/robocore\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eRoboCORE\u003c/a\u003e\n a chat bot operating on both Discord and Telegram serving the CORE community with various calculations and notifications.\u003c/p\u003e\n\u003cp\u003eA concept central to CORE is what is known as \u0026ldquo;the floor price\u0026rdquo; and in developing RoboCORE I had to learn how to calculate it properly. This concept is a bit hard to grasp, so this article tries to clear up the fog!\u003c/p\u003e\n\u003cp\u003eWhat is a floor price? It\u0026rsquo;s simply the lowest price CORE can ever reach. It\u0026rsquo;s not a floor in fiat, like the USD, but rather a floor \u003cstrong\u003emeasured in ETH\u003c/strong\u003e (or BTC), the assets CORE is traded against. So if those drop to zero in worth, then there is nothing CORE can do about that!\u003c/p\u003e","content":"The last month I have gotten involved in a fairly new crypto currency project called CORE , or cvault.finance . My main contribution is RoboCORE a chat bot operating on both Discord and Telegram serving the CORE community with various calculations and notifications.\nA concept central to CORE is what is known as \u0026ldquo;the floor price\u0026rdquo; and in developing RoboCORE I had to learn how to calculate it properly. This concept is a bit hard to grasp, so this article tries to clear up the fog!\nWhat is a floor price? It\u0026rsquo;s simply the lowest price CORE can ever reach. It\u0026rsquo;s not a floor in fiat, like the USD, but rather a floor measured in ETH (or BTC), the assets CORE is traded against. So if those drop to zero in worth, then there is nothing CORE can do about that!\nEarlier CORE was available only in a single trading pair CORE-ETH on Uniswap . Let\u0026rsquo;s pretend it still is, for the sake of most of this article, and we can expand to two trading pairs at the end.\nThere are three main mechanisms that together give CORE it\u0026rsquo;s floor price:\nThe fact that there is a fixed supply of CORE. 10000. There will never be more CORE minted. The fact that the CORE contracts prevent removing liquidity from the CORE-ETH pair. The Uniswap rules governing the price of a Uniswap trading pair. Ok, so there is only 10000 CORE, ever. Some of these CORE are in the trading pair, at the moment of writing there is 3333 CORE there, and 34667 ETH. So \u0026ldquo;outside\u0026rdquo; of the pair, in the hands of people, there must be 10000 - 3333 = 6667 COREs. Again, disregarding the second trading pair that just recently was started, let us just pretend that hasn\u0026rsquo;t happened :)\nNOTE: I sometimes write pair and sometimes pool. It\u0026rsquo;s the same thing.\nSome of you may even be unaware of how a Uniswap pair works. The simple mental image is that it is a trading pair of two coins. In this case CORE and ETH. It let\u0026rsquo;s you buy or sell CORE against ETH. And it does so without an order book, this is the beauty of Uniswap and so called decentralized exchanges. The pair itself consists of two piles of money, one pile of CORE and one pile of ETH. These two piles together is often referred to as a \u0026ldquo;pool\u0026rdquo;. The amount of money in the two piles, summed together, is called the liquidity of the pair. Trading is done by \u0026ldquo;swapping\u0026rdquo;, you basically put in CORE and get ETH out, or vice versa.\nNow\u0026hellip; mechanism number 2 says we can not remove liquidity from the pair. This is essential and means that the ETH in the pair can only be \u0026ldquo;removed\u0026rdquo; from the pair by buying it, using CORE. There is no other way, noone can just remove both chunks of money. The fact that liquidity is locked in is a key novel feature of the CORE trading pairs. The CORE project invented this idea and it has profound effects, including creating the price floor.\nThen we arrive at mechanism number 3. What is the price of a Uniswap trading pair? It\u0026rsquo;s trivial, the price at all times is simply \u0026lt;pooledETH\u0026gt; / \u0026lt;pooledCORE\u0026gt;. Simple!\nAt the time of writing price = 34667 / 3333 = 10.40 ETH/CORE. Ok, given this insight, this should mean that the lowest price is reached by increasing number of CORE in the pair and decreasing number of ETH in the pair. And the only way we can do that, is by selling CORE into the pair so we can pull out ETH. Let this sink in since it\u0026rsquo;s fundamental. We reach the lowest price when we have the highest amount of CORE and the lowest amount of ETH in the pair.\nSo when I sell 10 CORE into the pair, the price will go down. If I sell 10 more it will go down even more. If I sell ALL CORE THERE IS outside the pair, 6667 CORE, then the price should be down at the floor price, because there is no more CORE to put into the pool!\nUniswap trading dialog Link to heading A lot of people start fiddling with the Unsiwap trading dialog at this point, entering \u0026ldquo;6667\u0026rdquo; and seeing the price Uniswap would buy those COREs for, and mistakenly conclude this price to be the floor price. It is NOT. That\u0026rsquo;s the price you would get for selling 6667 CORE into the pair, but it is NOT the price CORE will have after you sold! So just drop that notion.\nThe math that comes below will also show how that particular price is calculated by Uniswap, but it\u0026rsquo;s still an uninteresting price - unless you really do have 6667 CORE to sell. The interesting price is what CORE will cost AFTER all CORE has been dumped into the pool, because if that would indeed occur - it would be lots and lots of little dumps, until the very last CORE was dumped. It would never be a single Megalodon dumping 6667 CORE.\nTime for math Link to heading So at this point I hope I have convinced you the reader that CORE will have it\u0026rsquo;s lowest price when ALL CORE is in the trading pair. All 10000 of them. The problem is, we don\u0026rsquo;t know how much ETH is left in the pair at that time. If we knew, then the price would simply be that amount of ETH divided by 10000, right?\nGoing back to Uniswap rules, there is a really slick rule that we must understand and that is the rule of \u0026ldquo;keeping k constant\u0026rdquo;. All Uniswap pairs abide by this rule, and it\u0026rsquo;s also the rule that figures out the price when you enter an amount to sell or buy in the Uniswap trading dialog.\nNow what is k? k is the name they have given to the mathematical product of the pooled assets. So k = \u0026lt;pooledETH\u0026gt; * \u0026lt;pooledCORE\u0026gt;. So right now k = 3333 * 34667 = 115545111. It\u0026rsquo;s just a number, not really something that can be interpreted to mean anything all by itself. But Uniswap will make sure it stays constant after each trade. This is what makes Uniswap tick. If k is 115545111 now, it should be so even after the next trade.\nThis means, that after you sell say\u0026hellip; 100 CORE into the pool, k should still be 115545111. But wait a minute, if you sell 100 CORE, then CORE in the pool will go from 3333 to 3433 so\u0026hellip; in order for k to stay constant the amount of ETH in the pool must be lowered. Well, duh, of course, because if you sell 100 CORE you want some ETH in return! So this determines the amount of ETH you will get for your 100 CORE, by determining how much ETH should be left in the pool.\nLet\u0026rsquo;s do the numbers. k = 3333 * 34667. You sell 100 CORE. So now k = 3433 * x where x is the amount of ETH that should still be in the pool. But k needs to stay constant so we can replace k in the equation with the value k had BEFORE the trade, so this gives us 115545111 = 3433 * x. And ok, we can now solve for x so x = 115545111 / 3433. What was x now again? It was the amount of ETH left in the pool after the trade. It turns out to be 33657.2. Since we had 34667 before, that must mean you got 34667 - 33657.2 = 1009.8 ETH for your 100 CORE. And the price ended thus up being 1009.8 / 100 which is 10.098 ETH/CORE. But the price now, after you sold, is actually 33657.2 / 3433 = 9.804 ETH/CORE! Aha! That\u0026rsquo;s interesting in itself, the price you get is not the same as the new price right after your transaction.\nSo this is how Uniswap figures out how much ETH you will get when you sell CORE! And of course the other way around too. And this obviously then also gives us amount of ETH still left in the pool.\nFinally we have reached the thought experiment - what happens if we sell ALL available CORE outside the pool into the pool? And\u0026hellip; is the end result the same if we sell it all in one big swoop, or if 1000s of people do it with 1000s of small paper cuts? The answer is, it does not matter how many trades we do it in, which is kinda logical. The k must remain at 115545111 at all times, it does not matter how many trades we use.\nSo yes, let\u0026rsquo;s see what happens if we sell ALL of CORE into the pair. It\u0026rsquo;s just the same as above, but this time we sell 6667 CORE instead of 100. Again, we want to know x - the amount of ETH left in the pool. Given k, this must be x = 115545111 / 10000. So we would have 11554.5111 ETH left in the pool. And then the new price is simply price = 11554.5111 / 10000 = 1.15545111 ETH/CORE.\nThis is our floor price. But do note it is a floor price in ETH. So if ETH goes down in fiat value, that means CORE\u0026rsquo;s floor in fiat also goes down, obviously. But it will NEVER EVER go down in ETH value below 1.15545111 ETH.\nWhat about\u0026hellip; fees Link to heading Ok, so indeed, we cheated with that part too. Uniswap takes a fee and that part goes back into the pool as added liquidity. This actually means that the amount of ETH slowly grows a little bit in the pair, slowly growing the floor price. This means that instead of doing x = oldk / (pooledCORE + addedCORE) we need to do x = oldk / (pooledCORE + (addedCORE * 0.997)) instead. So when calculating x, which is the amount of ETH left in the pool, we divide with a number slightly lower, which will make the amount of ETH left in the pool slightly higher (and thus the amount of ETH you receive for your CORE, a bit less). This means the ETH pool grows a little teeny bit, and k actually grows a little teeny bit, and thus floor price also grows a little teeny bit, with every trade. RoboCORE takes this into account, but for simple calculations it does not change the outcome much at all.\nWhat about\u0026hellip; the second pair? Link to heading Ah, yes. This makes it all much more complex! In the next article I will explain how to deal with two pairs, but it basically goes like this - instead of pouring all 10000 CORE into a single pair, we now need to do a balancing act. We need to pour some CORE into the CORE-ETH pair, and some into the new CORE-CBTC pair until there is no more CORE to pour.\nSo at that point, all 10000 CORE should be distributed in some way, between the two pairs. But how do we know how much we should put into each pair? Well, given that arbitrage would occur any stable floor price would have to be a price that is the same for both pairs. So the math problem boils down to finding the distribution of all 10000 CORE between the two pairs - that make them have the same price.\nWithout explaining in this article how we calculate that, I can show the current numbers. As we saw above we have 3333 CORE in the CORE-ETH pool. And there is now 615 CORE in the CORE-CBTC pool. Calculations say we would find the common price if we put 5048 COREs into the CORE-ETH pair and the rest, 1004 into the second pool. So 8381 and 1619 CORE respectively.\nThis makes a floor substantially higher, at around 1.63 ETH right now. One last final observation - with two pools the floor value can actually go down when valuated in ETH. Before it could not do that, but now with the second pair we need to take the CBTC-ETH rate into account also. So current floor does not only rely on ETH but also on CBTC, and that means the relationship between BTC and ETH will affect the floor, and subsequently the floor price valuated in ETH only can actually go down.\nThat\u0026rsquo;s all for today, keep HODLING :)\n"},{"title":"Revisiting Spry","permalink":"https://goran.krampe.se/2020/06/05/revisiting-spry/","summary":"\u003cp\u003eAfter a period of slower progress I got reignited regarding \u003ca href=\"https://sprylang.se\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSpry\u003c/a\u003e\n. So far I have written \u003ca href=\"http://goran.krampe.se/categories/spry/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ea lot of articles\u003c/a\u003e\n about Spry, and during this time things have evolved and changed.\u003c/p\u003e\n\u003cp\u003eSo I am now trying to \u0026ldquo;clean house\u0026rdquo; on where Spry stands today. This sweep through the old articles is a first step, then I will update the language manual to be 100% in sync with the implementation.\u003c/p\u003e\n\u003cp\u003eLet\u0026rsquo;s go through the articles from the beginning!\u003c/p\u003e","content":"After a period of slower progress I got reignited regarding Spry . So far I have written a lot of articles about Spry, and during this time things have evolved and changed.\nSo I am now trying to \u0026ldquo;clean house\u0026rdquo; on where Spry stands today. This sweep through the old articles is a first step, then I will update the language manual to be 100% in sync with the implementation.\nLet\u0026rsquo;s go through the articles from the beginning!\nThings wrong in article one :\nfunci is now called method, indicating it is a message to a receiver on the left if as been changed to the more Smalltalkish then:else: (but shorter than ifTrue:ifFalse: and reads nice) return is now ^ just like in Smalltalk In article two :\nContext is now called Map. It\u0026rsquo;s the same as a Smalltalk Dictionary, but \u0026ldquo;Map\u0026rdquo; is a more popular term these days, and shorter. Get words use $-prefix, not ^ (which is return). This actually looks kinda ok, it makes them resemble \u0026ldquo;variables\u0026rdquo; from other languages. The idea with a pluggable parser\u0026hellip; I think I will skip that and replace with something else in pure Spry! The scoping prefixes . and .. have been removed and replaced with another way to assign. I wrote \u0026ldquo;This means Ni maintains no call stack of its own.\u0026rdquo; - no idea what I meant by that. Spry indeed has a stack of activation records. In article three :\nThere is no ifelse, instead we have then:else:, else:then:, else:, then:. The argwords design mistake is still here, but\u0026hellip; can be avoided by not using argwords nested, so use [:x :y ^[x + y]] instead of [^[:x + :y]]. So it will probably have to stay. Single ? is not used anymore, we can use set? to check if an unevaluated word is bound, like x set? Meaning of scopes are now (I have removed . and ..): x - look in locals and then all the way out. @x - look in closest surrounding Map (self). Optional arguments have not been added, I don\u0026rsquo;t think I ever will add. \u0026amp; has been changed to Smalltalk style , for concatenation, but leaning towards +. undef vs nil is slightly different: nil is a value that means \u0026ldquo;no value\u0026rdquo; undef has been removed, it was a fun experiment ?-marks are used for funcs/methods that return booleans, convention. !-mark is still unused. self is as the receiver for methods. It can be anything. context is locals, returns the Map of the local scope. activation returns the current activation, not yet explored much but it\u0026rsquo;s there! In article four :\nI later opted to call a Dictionary a Map, so it\u0026rsquo;s Map now :) The bindings word is now locals. The description of object is partly the way it works, yes, it takes a Map as argument and returns an \u0026ldquo;object\u0026rdquo;. But\u0026hellip; this is done using tags that\u0026rsquo;s not described in this article. Also, the traits idea and thoughts around that is not what has been implemented later. The current Spry instead is exploring if methods can be defined for things with specific tags, and then if those methods can be automatically composed into \u0026ldquo;polymethods\u0026rdquo; so that two different modules can define methods with the same name - and they are \u0026ldquo;merged\u0026rdquo; into a polymethod that get\u0026rsquo;s bound to that name. When invoked the polymethod should \u0026ldquo;internally\u0026rdquo; pick which method to execute. In article five :\nYes, renamed to Spry. But\u0026hellip; it\u0026rsquo;s sprylang.se, not .org In article six :\nYes, base idea of using compressed \u0026ldquo;Spry code\u0026rdquo; and store in a fast embedded database still stands! But I now have Rocksdb instead of Sophia, and a pure Nim implementation of Snappy instead of lz4 (it was too hard to get on various platforms) In article seven Yes, the current modules is implemented as described. Not tested much, but yes. I still think the base ideas stand. In article eight I did fix so that Foo::bar first finds Foo, and then looks in it. So it works for Maps in general, not just modules. And yes, you can then shadow a module with a global. To access \u0026ldquo;map members\u0026rdquo; I instead added @x syntax. Since self is now bound to the receiver of methods, this resolves members also. One issue though, if you use blocks (and not funcs) then nested blocks in a method sent as parameters to other methods will obviously not resolve to the lexical self, but to the receiving self. Changing the block to a func solves this. Lossless AST was something I did experiment with, but dropped it. A bit too crazy perhaps. So\u0026hellip; otherwise it basically sounds like a good plan, but not used much (or implemented much) yet. In article nine This article is mostly \u0026ldquo;fluff\u0026rdquo; but there is one important thing I need to improve - \u0026ldquo;Live within the prototype\u0026rdquo;. In other words, Spry code should be edited, browsed and debugged in Spry tools. I need to try to get that going! In article ten Nothing to note, except that yeah, Nim is fast and Spry is slow :) In article eleven Most of this article seems quite correct and according to plan. And finally, in article twelve Most here seems fine too. Latest Changes Link to heading I have added := for reassignment. If no existing binding is found there will be an error (not fixed yet). So = will work fine for single assignment, and will assign in local scope. And := signify reassignment and will lookup outwards before assigning. I have removed undef. It felt neat but get\u0026rsquo;s confusing. Maps can still hold nil, it\u0026rsquo;s a valid value - if you want to check for a missing binding you will have to use explicit calls to do it instead, just as in Smalltalk. I have removed . and .. scoping words. They can instead be implemented as direct access to locals or activation parent lookup: etc. I have implemented a base catch:, throw and try:catch: mechanism but more to come. More on error handling in the next article!\n"},{"title":"About","permalink":"https://goran.krampe.se/about/","summary":"\u003cp\u003eI am Göran Krampe and this is my blog where I mainly write about \u003cstrong\u003esoftware development\u003c/strong\u003e. Currently I work at\n\u003ca href=\"https://www.sinch.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSinch\u003c/a\u003e\n.\nBefore that I worked at a company called \u003ca href=\"https://www.bioservo.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eBioservo Technologies\u003c/a\u003e\n building software supporting \u003cstrong\u003ereally cool\u003c/strong\u003e \u003ca href=\"https://www.youtube.com/watch?v=ZshA7Q37iws\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003esoft robotic gloves\u003c/a\u003e\n.\u003c/p\u003e\n\u003cp\u003eDuring three years I worked at \u003ca href=\"http://3dicc.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003e3DICC\u003c/a\u003e\n developing the \u003cstrong\u003ecoolest collaborative Virtual Reality system\u003c/strong\u003e on earth - \u003ca href=\"http://3dicc.com/terf-product-details/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eTerf\u003c/a\u003e\n.\u003c/p\u003e\n\u003cp\u003eAnd going all the way back to 1994-2011 I worked as a software developer consultant in various companies in Stockholm. In 2011 I started my own one-man-firm as a freelance software developer - \u003ca href=\"http://www.krampe.se\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eKrampe Dynamic Development\u003c/a\u003e\n - available for work both in Stockholm on site and internationally by remote.\u003c/p\u003e","content":"I am Göran Krampe and this is my blog where I mainly write about software development. Currently I work at Sinch . Before that I worked at a company called Bioservo Technologies building software supporting really cool soft robotic gloves .\nDuring three years I worked at 3DICC developing the coolest collaborative Virtual Reality system on earth - Terf .\nAnd going all the way back to 1994-2011 I worked as a software developer consultant in various companies in Stockholm. In 2011 I started my own one-man-firm as a freelance software developer - Krampe Dynamic Development - available for work both in Stockholm on site and internationally by remote.\nThis blog’s name “Roads Less Taken” refers to the poem called “The Road Not Taken” by Robert Frost which describes how a traveler in a forest decides to take one of the two roads in front of him – “the one less traveled by”. Here you can find the full poem , I especially like that last part:\nTwo roads diverged in a wood, and I\u0026ndash; I took the one less traveled by, And that has made all the difference. — Robert Frost, 1916\nI think that sets the mood for what I would like to write about in software development on this blog, namely that you can gain a lot by choosing “Roads” (think tools, methods, interests and techniques) that are “Less Taken” (not among the most popular that everyone else uses). Daring to be different and choosing the right tool for the job. Or at least open your mind and learn. :)\n"},{"title":"Dart","permalink":"https://goran.krampe.se/dart/","summary":"\u003cp\u003eI have followed \u003ca href=\"https://dart.dev\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eDart\u003c/a\u003e\n from the corner of my eye since the inception - after all, \u003ca href=\"https://en.wikipedia.org/wiki/Lars_Bak_%28computer_programmer%29\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eLars Bak\u003c/a\u003e\n, one of the creators is a very well known man in the Smalltalk/Self/OO world, so it had to be interesting!\u003c/p\u003e\n\u003cp\u003eIn the beginning Dart lived a life away from the spotlight, trying to become a \u0026ldquo;better Javascript\u0026rdquo; sure is an impossible fight to pick. But with the birth of \u003ca href=\"https://flutter.io\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eFlutter\u003c/a\u003e\n and the hard work to make Dart mature over the years, including moving to Dart 2.0 with a sound static type system that actually \u0026ldquo;feels nice\u0026rdquo; even for a Smalltalker - Dart is now an \u003cstrong\u003eextremely interesting platform.\u003c/strong\u003e\u003c/p\u003e","content":"I have followed Dart from the corner of my eye since the inception - after all, Lars Bak , one of the creators is a very well known man in the Smalltalk/Self/OO world, so it had to be interesting!\nIn the beginning Dart lived a life away from the spotlight, trying to become a \u0026ldquo;better Javascript\u0026rdquo; sure is an impossible fight to pick. But with the birth of Flutter and the hard work to make Dart mature over the years, including moving to Dart 2.0 with a sound static type system that actually \u0026ldquo;feels nice\u0026rdquo; even for a Smalltalker - Dart is now an extremely interesting platform.\nAt work I am betting hard on Dart, not only for mobile apps via Flutter, but also server side using Aqueduct and a slew of other packages .\n"},{"title":"Nim","permalink":"https://goran.krampe.se/nim/","summary":"\u003cp\u003eIn 2014 I discovered the programming language called \u003ca href=\"http://nim-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNim\u003c/a\u003e\n, earlier named  Nimrod, created by Andreas Rumpf. Its a \u003cstrong\u003ebeast\u003c/strong\u003e of a language, not at all like my other favorite minimalistic dynamically typed \u003ca href=\"/smalltalk\" \u003eSmalltalk\u003c/a\u003e\n. But nevertheless, this \u0026ldquo;beast\u0026rdquo; feels more like a candy box than an \u003ca href=\"http://en.wikipedia.org/wiki/C%2B%2B\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eendless maze\u003c/a\u003e\n, and several of its characteristics makes it very compelling even though it\u0026rsquo;s not \u0026ldquo;like Smalltalk\u0026rdquo;.\u003c/p\u003e\n\u003cp\u003eI have written \u003ca href=\"/categories/nim\" \u003eseveral articles on Nim\u003c/a\u003e\n documenting my adventures into this new \u003cem\u003eLand Of Magic\u003c/em\u003e. It\u0026rsquo;s not a puristic minimal language like Lisp or Smalltalk, but meant to be practical and fast. Practical and pragmatic as \u0026ldquo;Python\u0026rdquo;. Fast as \u0026ldquo;C\u0026rdquo;.\u003c/p\u003e","content":"In 2014 I discovered the programming language called Nim , earlier named Nimrod, created by Andreas Rumpf. Its a beast of a language, not at all like my other favorite minimalistic dynamically typed Smalltalk . But nevertheless, this \u0026ldquo;beast\u0026rdquo; feels more like a candy box than an endless maze , and several of its characteristics makes it very compelling even though it\u0026rsquo;s not \u0026ldquo;like Smalltalk\u0026rdquo;.\nI have written several articles on Nim documenting my adventures into this new Land Of Magic. It\u0026rsquo;s not a puristic minimal language like Lisp or Smalltalk, but meant to be practical and fast. Practical and pragmatic as \u0026ldquo;Python\u0026rdquo;. Fast as \u0026ldquo;C\u0026rdquo;.\nLearning Nim Link to heading http://nim-lang.org/documentation.html - Read the two tutorials and the language documentation. http://nim-by-example.github.io - Very nice little mini book on Nim. http://rosettacode.org/wiki/Nim - Almost 500 Nim snippets. http://learnxinyminutes.com/docs/nim - Again a quick intro. Articles on Nim Link to heading http://picheta.me/articles/2013/10/about-nimrods-features.html - Skims through several of the language features http://blog.ldlework.com/2015/05/01/a-cursory-look-at-meta-programming-in-nim/ - Explores macros and templates https://github.com/Araq/Nimrod/wiki/Nim-for-C-programmers - Describes differences from a C perspective. http://goran.krampe.se/categories/nim - My own various articles on this blog, take your pick! http://vocalbit.com/posts/exploring-type-classes-in-nimrod.html - Very interesting description of the experimental typeclass mechanism. Videos Link to heading http://media.koeln.ccc.de/events/gpn/gpn14/mp4/gpn14-5892-de-Nimrod_h264-hq.mp4 - In German, pretty detailed. "},{"title":"Smalltalk","permalink":"https://goran.krampe.se/smalltalk/","summary":"\u003cp\u003eSince learning \u003ca href=\"http://www.world.st\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSmalltalk\u003c/a\u003e\n at KTH in around 1994 - we used VisualWorks 1.0 IIRC - I have been deeply in love with both the language, its mindset and the community with all its diversity. During many years I was very active in the \u003ca href=\"http://squeak.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSqueak\u003c/a\u003e\n community and I have also been using \u003ca href=\"http://pharo.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ePharo\u003c/a\u003e\n for various development tasks.\u003c/p\u003e\n\u003cp\u003eToday in 2019 I would say \u003cstrong\u003ePharo is the leading open source Smalltalk dialect\u003c/strong\u003e, sharing lots of resources with its ancestor, Squeak, especially the \u003ca href=\"http://www.mirandabanda.org/cogblog/about-cog/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eCog VM\u003c/a\u003e\n, these days going under the name \u003ca href=\"http://www.opensmalltalk.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eOpenSmalltalk\u003c/a\u003e\n, that enables Pharo and Squeak to still be competitive alternatives.\u003c/p\u003e","content":"Since learning Smalltalk at KTH in around 1994 - we used VisualWorks 1.0 IIRC - I have been deeply in love with both the language, its mindset and the community with all its diversity. During many years I was very active in the Squeak community and I have also been using Pharo for various development tasks.\nToday in 2019 I would say Pharo is the leading open source Smalltalk dialect, sharing lots of resources with its ancestor, Squeak, especially the Cog VM , these days going under the name OpenSmalltalk , that enables Pharo and Squeak to still be competitive alternatives.\nThe elegance of Smalltalk, through its careful design and very powerful toolset - still today makes it a compelling tool for many tasks. The Design Principles Behind Smalltalk -article from Byte magazine 1981 is a must read for anyone seriously interested in programming languages.\nGood Design: A system should be built with a minimum set of unchangeable parts; those parts should be as general as possible; and all parts of the system should be held in a uniform framework. — Dan Ingalls, Byte magazine 1981\n"},{"title":"Spry","permalink":"https://goran.krampe.se/spry/","summary":"\u003cp\u003eI have always entertained thoughts of making my own programming language. Now that I have found a really fast implementation language that I actually enjoy working in - \u003ca href=\"/nim\" \u003eNim\u003c/a\u003e\n - I started doing it.\u003c/p\u003e\n\u003cp\u003eThe language is called \u003ca href=\"http://sprylang.se\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSpry\u003c/a\u003e\n but was initially named Ni (as in the Knights Who Say\u0026hellip;), but I \u003ca href=\"/2016/04/08/ni-is-now-spry\" \u003edecided to rename it\u003c/a\u003e\n.\u003c/p\u003e\n\u003cp\u003eSpry is a dynamically typed, 100% live, homoiconic minimalistic language with pervasive use of closures for control structures, non local returns, Smalltalk and Rebol inspired semantics and syntax, and soon to come pretty good OOP support. It\u0026rsquo;s a pure interpreter but can very easily mix with Nim for maximum speed.\u003c/p\u003e","content":"I have always entertained thoughts of making my own programming language. Now that I have found a really fast implementation language that I actually enjoy working in - Nim - I started doing it.\nThe language is called Spry but was initially named Ni (as in the Knights Who Say\u0026hellip;), but I decided to rename it .\nSpry is a dynamically typed, 100% live, homoiconic minimalistic language with pervasive use of closures for control structures, non local returns, Smalltalk and Rebol inspired semantics and syntax, and soon to come pretty good OOP support. It\u0026rsquo;s a pure interpreter but can very easily mix with Nim for maximum speed.\nI have written several articles on Spry documenting my adventures. Everything else is found on the Spry homepage .\n"},{"title":"Messaging","permalink":"https://goran.krampe.se/messaging/","summary":"\u003ch2 id=\"slides\"\u003e\n  Slides\n  \u003ca class=\"heading-link\" href=\"#slides\"\u003e\n    \u003ci class=\"fa-solid fa-link\" aria-hidden=\"true\" title=\"Link to heading\"\u003e\u003c/i\u003e\n    \u003cspan class=\"sr-only\"\u003eLink to heading\u003c/span\u003e\n  \u003c/a\u003e\n\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"http://krampe.se/kth-messaging-2018.pdf\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttp://krampe.se/kth-messaging-2018.pdf\u003c/a\u003e\n - These are my slides I showed at the lecture.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"mqtt\"\u003e\n  MQTT\n  \u003ca class=\"heading-link\" href=\"#mqtt\"\u003e\n    \u003ci class=\"fa-solid fa-link\" aria-hidden=\"true\" title=\"Link to heading\"\u003e\u003c/i\u003e\n    \u003cspan class=\"sr-only\"\u003eLink to heading\u003c/span\u003e\n  \u003c/a\u003e\n\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"http://www.hivemq.com/demos/websocket-client/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttp://www.hivemq.com/demos/websocket-client/\u003c/a\u003e\n - This is a nice web client that can be used for test purposes. Enter mqtt.evothings.com, port 1884 and connect!\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://zoetrope.io/tech-blog/brief-practical-introduction-mqtt-protocol-and-its-application-iot\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttps://zoetrope.io/tech-blog/brief-practical-introduction-mqtt-protocol-and-its-application-iot\u003c/a\u003e\n - Best quick but fairly complete introduction!\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"http://www.hivemq.com/blog/mqtt-essentials-part-1-introducing-mqtt\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttp://www.hivemq.com/blog/mqtt-essentials-part-1-introducing-mqtt\u003c/a\u003e\n - Pretty good series of articles\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"http://www.eclipse.org/paho/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttp://www.eclipse.org/paho/\u003c/a\u003e\n - Client implementation of choice, in many languages.\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/mqtt/mqtt.github.io/wiki/servers\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003e https://github.com/mqtt/mqtt.github.io/wiki/servers\u003c/a\u003e\n - Lots of available servers, we use VerneMQ.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"dds\"\u003e\n  DDS\n  \u003ca class=\"heading-link\" href=\"#dds\"\u003e\n    \u003ci class=\"fa-solid fa-link\" aria-hidden=\"true\" title=\"Link to heading\"\u003e\u003c/i\u003e\n    \u003cspan class=\"sr-only\"\u003eLink to heading\u003c/span\u003e\n  \u003c/a\u003e\n\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.slideshare.net/PrismTech1/dds-in-action-part-1\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttps://www.slideshare.net/PrismTech1/dds-in-action-part-1\u003c/a\u003e\n - A pretty nice presentation!\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"painter\"\u003e\n  Painter\n  \u003ca class=\"heading-link\" href=\"#painter\"\u003e\n    \u003ci class=\"fa-solid fa-link\" aria-hidden=\"true\" title=\"Link to heading\"\u003e\u003c/i\u003e\n    \u003cspan class=\"sr-only\"\u003eLink to heading\u003c/span\u003e\n  \u003c/a\u003e\n\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://mqtt.evothings.com/painter/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttps://mqtt.evothings.com/painter/\u003c/a\u003e\n - The Painter app that you can run if you are viewing this webpage in the Evothings Viewer!\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/gokr/mqtt-painter\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttps://github.com/gokr/mqtt-painter\u003c/a\u003e\n - The Painter app source repo, clone it, then drag and drop evothings.json onto Evothings Studio\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"http://www.eclipse.org/paho/clients/js/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ehttp://www.eclipse.org/paho/clients/js/\u003c/a\u003e\n - This is the library we use in the app to do MQTT.\u003c/li\u003e\n\u003c/ul\u003e","content":" Slides Link to heading http://krampe.se/kth-messaging-2018.pdf - These are my slides I showed at the lecture. MQTT Link to heading http://www.hivemq.com/demos/websocket-client/ - This is a nice web client that can be used for test purposes. Enter mqtt.evothings.com, port 1884 and connect! https://zoetrope.io/tech-blog/brief-practical-introduction-mqtt-protocol-and-its-application-iot - Best quick but fairly complete introduction! http://www.hivemq.com/blog/mqtt-essentials-part-1-introducing-mqtt - Pretty good series of articles http://www.eclipse.org/paho/ - Client implementation of choice, in many languages. https://github.com/mqtt/mqtt.github.io/wiki/servers - Lots of available servers, we use VerneMQ. DDS Link to heading https://www.slideshare.net/PrismTech1/dds-in-action-part-1 - A pretty nice presentation! Painter Link to heading https://mqtt.evothings.com/painter/ - The Painter app that you can run if you are viewing this webpage in the Evothings Viewer! https://github.com/gokr/mqtt-painter - The Painter app source repo, clone it, then drag and drop evothings.json onto Evothings Studio http://www.eclipse.org/paho/clients/js/ - This is the library we use in the app to do MQTT. "},{"title":"Writing Arduinobot in Nim","permalink":"https://goran.krampe.se/2017/10/26/writing-arduinobot-in-nim/","summary":"\u003cp\u003eIn the \u003ca href=\"https://project.ecraft2learn.eu/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eeCraft2Learn project\u003c/a\u003e\n which Evothings is participating in we were looking at various ways\n\u003ca href=\"http://nim-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNim\u003c/a\u003e\n is an awesome programming language and this article is a \u003cstrong\u003ewhirlwind-copy-paste-into-your-terminal-as-you-read-thing\u003c/strong\u003e to show how you install Nim, write a small program, compile it and package it in a very short time.\u003c/p\u003e\n\u003cp\u003eTo spice it up, for \u003cstrong\u003eno specific reason at all\u003c/strong\u003e, we are doing it all inside a \u003ca href=\"http://linuxcontainers.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eLinux Container\u003c/a\u003e\n - a fast virtual environment to work in. It\u0026rsquo;s just a nice way to have a clean environment and to ensure that you as a reader see the same results as I do.\u003c/p\u003e","content":"In the eCraft2Learn project which Evothings is participating in we were looking at various ways Nim is an awesome programming language and this article is a whirlwind-copy-paste-into-your-terminal-as-you-read-thing to show how you install Nim, write a small program, compile it and package it in a very short time.\nTo spice it up, for no specific reason at all, we are doing it all inside a Linux Container - a fast virtual environment to work in. It\u0026rsquo;s just a nice way to have a clean environment and to ensure that you as a reader see the same results as I do.\nYou can of course just skip the part on LXC and go directly to Nim fun . :)\nGet going with LXC Link to heading NOTE: The following presumes you are on a Ubuntu box, virtual should work fine.\nLinux Containers let\u0026rsquo;s us run an isolated full Linux system inside a Linux host, kinda like KVM/Virtualbox but much more lightweight, similar to Docker. Contrary to Docker though, LXC is not constrained to a single process. Instead it behaves like a full VM which is much more what I want!\nLXD is then a REST based daemon sitting on top of LXC that also gives us nice CLI tools operating against the daemon. See this nice blog article series on LXD version 2.0 . Let\u0026rsquo;s install LXD and get us a clean spanking new Ubuntu 17.04 environment!\nNOTE: More detailed steps are found here and a cheat sheet sudo apt install lxd lxd-client zfsutils-linux newgrp lxd Then step through a bunch of questions, just using defaults work fine:\nsudo lxd init So that dance felt long, but\u0026hellip; it was worth it!\nFire up a fresh Ubuntu 17.04 Link to heading Now we can fire up a fresh Ubuntu, say version 17.04, and call it nim:\nlxc launch ubuntu:17.04 nim We can now see it\u0026rsquo;s running:\nlxc list And we can get a root shell inside it:\nlxc exec nim -- bash But better to login properly as the ubuntu user:\nlxc exec nim -- su --login ubuntu Install Nim Link to heading Today the preferred way to install Nim on Linux is to use choosenim , a neat toolchain multiplexer which makes it easy to switch between different versions of the Nim compiler. First we install GCC though, needed by choosenim:\nsudo apt install gcc Then we can do the dance to install choosenim and nim:\ncurl https://nim-lang.org/choosenim/init.sh -sSf | sh echo \u0026quot;export PATH=~/.nimble/bin:\\$PATH\u0026quot; \u0026gt;\u0026gt; ~/.bashrc export PATH=~/.nimble/bin:$PATH And we should have the Nim compiler in our path:\nubuntu@nim:~$ nim --version Nim Compiler Version 0.17.2 (2017-09-07) [Linux: amd64] Copyright (c) 2006-2017 by Andreas Rumpf git hash: 811fbdafd958443ddac98ad58c77245860b38620 active boot switches: -d:release Create a Nim program Link to heading Allright! Time to make a small Nim program called \u0026ldquo;moni\u0026rdquo; - don\u0026rsquo;t ask why. First create a directory to work in, obviously we should use git etc, but I leave that to you. We also run nimble init to get a skeleton of a so called .nimble file. Nimble is the \u0026ldquo;npm\u0026rdquo; of the Nim ecosystem. And a nimble file is similar to packages.json for npm.\nmkdir moni \u0026amp;\u0026amp; cd moni nimble init Now, let\u0026rsquo;s add some more lines to moni.nimble, starting with these three in the top section:\nbinDir = \u0026quot;bin\u0026quot; bin = @[\u0026quot;moni\u0026quot;] skipExt = @[\u0026quot;nim\u0026quot;] This tells nimble that this package produces binaries and will put them in the directory bin when building. We also tell it that we have a list of binaries, the syntax for a seq in Nim, which is a dynamic array, looks like @[ a, b, ... c ]. So we add \u0026quot;moni\u0026quot; to that list, the executable\u0026rsquo;s name.\nFinally we also tell Nimble that when this package later is installed, skip installing all .nim files, since we are not making a Nim library, we only want the compiled executable to be installed.\nLet\u0026rsquo;s also add a dependency called docopt which is a really nice Nim library for parsing command line arguments, to the bottom list of dependencies:\nrequires \u0026quot;docopt\u0026quot; The full file should now look like this:\n# Package version = \u0026#34;0.1.0\u0026#34; author = \u0026#34;Göran Krampe\u0026#34; description = \u0026#34;A simple MQTT publisher tool.\u0026#34; license = \u0026#34;MIT\u0026#34; binDir = \u0026#34;bin\u0026#34; bin = @[\u0026#34;moni\u0026#34;] skipExt = @[\u0026#34;nim\u0026#34;] # Dependencies requires \u0026#34;nim \u0026gt;= 0.17.2\u0026#34; requires \u0026#34;docopt\u0026#34; Ok, and finally, let\u0026rsquo;s write some code. To begin with the program will just parse out arguments, and can show help, save this as moni.nim:\nimport docopt let help = \u0026#34;\u0026#34;\u0026#34; moni - A simple MQTT publisher tool. Usage: moni [-u username] [-p password] [-s mqtturl] \u0026lt;topic\u0026gt; \u0026lt;payload\u0026gt; moni (-h | --help) moni (-v | --version) Options: -u username Set username [default: test]. -p password Set password [default: test]. -s mqtturl Set URL for the MQTT server [default: tcp://localhost:1883] -h --help Show this screen. -v --version Show version. \u0026#34;\u0026#34;\u0026#34; var args = docopt(help, version = \u0026#34;0.1.0\u0026#34;) # Get parameters let username = $args[\u0026#34;-u\u0026#34;] let password = $args[\u0026#34;-p\u0026#34;] let mqtturl = $args[\u0026#34;-s\u0026#34;] let topic = $args[\u0026#34;\u0026lt;topic\u0026gt;\u0026#34;] let payload = $args[\u0026#34;\u0026lt;payload\u0026gt;\u0026#34;] echo \u0026#34;Username: \u0026#34; \u0026amp; $username echo \u0026#34;Password: \u0026#34; \u0026amp; $password echo \u0026#34;Server: \u0026#34; \u0026amp; $mqtturl echo \u0026#34;Topic: \u0026#34; \u0026amp; $topic echo \u0026#34;Payload: \u0026#34; \u0026amp; $payload quit Time to compile it!\nIf we want nimble to suck down dependencies automatically for us, then we build using nimble, it will use the moni.nimble to figure out what to do:\nnimble build And we can then run the binary:\n./bin/moni If we supply a topic and payload we can see default values for options:\n./bin/moni topic payload We can also compile the moni.nim file directly, simply using the nim compiler - but that would have failed initially since we didn\u0026rsquo;t have the docopt dependency installed. But do try it now:\nnim c moni.nim The nim compiler will however put the binary in your current directory, not in bin.\nOk, let\u0026rsquo;s get serious and add some real MQTT code into this. First add a dependency in moni.nimble to the Nim wrapper of the PAHO MQTT C library, by adding the following line at the bottom of moni.nimble:\nrequires \u0026quot;https://github.com/barnybug/nim-mqtt\u0026quot; So with nimble we can require using direct URLs to git or mercurial repositories as well, we are not limited to the pulished known packages in the Nimble catalog. Then make the code look like this instead:\nimport docopt, mqtt, MQTTClient let help = \u0026#34;\u0026#34;\u0026#34; moni - A simple MQTT publisher tool. Usage: moni [-u username] [-p password] [-s mqtturl] \u0026lt;topic\u0026gt; \u0026lt;payload\u0026gt; moni (-h | --help) moni (-v | --version) Options: -u username Set username [default: test]. -p password Set password [default: test]. -s mqtturl Set URL for the MQTT server [default: tcp://localhost:1883] -h --help Show this screen. -v --version Show version. \u0026#34;\u0026#34;\u0026#34; var args = docopt(help, version = \u0026#34;0.1.0\u0026#34;) # Get parameters let username = $args[\u0026#34;-u\u0026#34;] let password = $args[\u0026#34;-p\u0026#34;] let mqtturl = $args[\u0026#34;-s\u0026#34;] let topic = $args[\u0026#34;\u0026lt;topic\u0026gt;\u0026#34;] let payload = $args[\u0026#34;\u0026lt;payload\u0026gt;\u0026#34;] # Print them echo \u0026#34;Username: \u0026#34; \u0026amp; $username echo \u0026#34;Password: \u0026#34; \u0026amp; $password echo \u0026#34;Server: \u0026#34; \u0026amp; $mqtturl echo \u0026#34;Topic: \u0026#34; \u0026amp; $topic echo \u0026#34;Payload: \u0026#34; \u0026amp; $payload const ClientId = \u0026#34;nim-mqtt-pub\u0026#34; proc connect(username, password, mqtturl: string): MQTTClient = ## Connect to MQTT server result = newClient(mqtturl, ClientId, MQTTPersistenceType.None) var connectOptions = newConnectOptions() connectOptions.username = username connectOptions.password = password result.connect(connectOptions) proc disconnect(client: MQTTClient) = ## Disconnect the client client.disconnect(1000) client.destroy() proc publish(client: MQTTClient, topic, payload: string) = ## Publish a payload on a topic discard client.publish(topic, payload, QOS.AtMostOnce, false) try: var client = connect(username, password, mqtturl) client.publish(topic, payload) client.disconnect() echo \u0026#34;Payload sent\u0026#34; except MQTTError: quit(\u0026#34;MQTT exception: \u0026#34; \u0026amp; getCurrentExceptionMsg(), QuitFailure) quit(QuitSuccess) A few quick remarks about the code:\nWhen you see $something, that\u0026rsquo;s Nim\u0026rsquo;s way of saying something.toString() When you see \u0026amp; that\u0026rsquo;s string concatenation. You also see three procs that we later call inside the try: block. A proc is just another name for function. In the connect proc there is a variable called result. It\u0026rsquo;s an implicit variable available in all procs that have a return value and represents the thing that will be returned. In the publish proc we see the discard statement, it\u0026rsquo;s used to \u0026ldquo;throw away\u0026rdquo; return values that we ignore, it has to be done explicitly in Nim or the compiler will complain. If all goes well we quit with success, otherwise with the exception message and failure . Then we build again:\nnimble build And let\u0026rsquo;s try running it aginst a public demo broker:\n./bin/moni -s tcp://broker.hivemq.com:1883 sensor/99 '{\u0026quot;temp\u0026quot;: 25.4, \u0026quot;flow\u0026quot;: 0.7}' could not load: libpaho-mqtt3c.so compile with -d:nimDebugDlOpen for more information Oops! Ok, so the MQTT wrapper library needs the C library of course! And it\u0026rsquo;s not available as a deb, so let\u0026rsquo;s get our hands dirty:\nsudo apt install libssl-dev make Then we can build and install Paho C from source:\ncd ~ git clone https://github.com/eclipse/paho.mqtt.c.git cd paho.mqtt.c make sudo make install sudo ldconfig Let\u0026rsquo;s try building again:\ncd ~/moni nimble build And finally we can hopefully publish via MQTT, let\u0026rsquo;s try it once more:\n./bin/moni -s tcp://broker.hivemq.com:1883 cucumber/99 \u0026#39;{\u0026#34;temp\u0026#34;: 25.4, \u0026#34;flow\u0026#34;: 0.7}\u0026#39; If it ends with \u0026ldquo;Payload sent\u0026rdquo; we are all good! We just sent a JSON payload to the cucumber/99 topic.\nHiveMQ accepts anonymous connections on the test broker so we don\u0026rsquo;t need to specify username/password. In order to verify that the above actually worked, you can point your browser to http://www.hivemq.com/demos/websocket-client/ and connect on port 8000 to broker.hivemq.com, then add topic subscription to \u0026ldquo;cucumber/#\u0026rdquo; and run the above command once more. If all works you should see the message appear!\nNow, to round things off we can install this little program too, locally for your user inside the LXC container that is. :) You just run nimble install and then we have it in our path.\nOk, that\u0026rsquo;s all folks - you are now a Nim hacker!\n"},{"title":"Nim crash course in LXC","permalink":"https://goran.krampe.se/2017/10/24/nim-crash-course-inside-lxc/","summary":"\u003cp\u003e\u003ca href=\"http://nim-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNim\u003c/a\u003e\n is an awesome programming language and this article is a \u003cstrong\u003ewhirlwind-copy-paste-into-your-terminal-as-you-read-thing\u003c/strong\u003e to show how you install Nim, write a small program, compile it and package it in a very short time.\u003c/p\u003e\n\u003cp\u003eTo spice it up, for \u003cstrong\u003eno specific reason at all\u003c/strong\u003e, we are doing it all inside a \u003ca href=\"http://linuxcontainers.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eLinux Container\u003c/a\u003e\n - a fast virtual environment to work in. It\u0026rsquo;s just a nice way to have a clean environment and to ensure that you as a reader see the same results as I do.\u003c/p\u003e","content":"Nim is an awesome programming language and this article is a whirlwind-copy-paste-into-your-terminal-as-you-read-thing to show how you install Nim, write a small program, compile it and package it in a very short time.\nTo spice it up, for no specific reason at all, we are doing it all inside a Linux Container - a fast virtual environment to work in. It\u0026rsquo;s just a nice way to have a clean environment and to ensure that you as a reader see the same results as I do.\nYou can of course just skip the part on LXC and go directly to Nim fun . :)\nGet going with LXC Link to heading NOTE: The following presumes you are on a Ubuntu box, virtual should work fine.\nLinux Containers let\u0026rsquo;s us run an isolated full Linux system inside a Linux host, kinda like KVM/Virtualbox but much more lightweight, similar to Docker. Contrary to Docker though, LXC is not constrained to a single process. Instead it behaves like a full VM which is much more what I want!\nLXD is then a REST based daemon sitting on top of LXC that also gives us nice CLI tools operating against the daemon. See this nice blog article series on LXD version 2.0 . Let\u0026rsquo;s install LXD and get us a clean spanking new Ubuntu 17.04 environment!\nNOTE: More detailed steps are found here and a cheat sheet sudo apt install lxd lxd-client zfsutils-linux newgrp lxd Then step through a bunch of questions, just using defaults work fine:\nsudo lxd init So that dance felt long, but\u0026hellip; it was worth it!\nFire up a fresh Ubuntu 17.04 Link to heading Now we can fire up a fresh Ubuntu, say version 17.04, and call it nim:\nlxc launch ubuntu:17.04 nim We can now see it\u0026rsquo;s running:\nlxc list And we can get a root shell inside it:\nlxc exec nim -- bash But better to login properly as the ubuntu user:\nlxc exec nim -- su --login ubuntu Install Nim Link to heading Today the preferred way to install Nim on Linux is to use choosenim , a neat toolchain multiplexer which makes it easy to switch between different versions of the Nim compiler. First we install GCC though, needed by choosenim:\nsudo apt install gcc Then we can do the dance to install choosenim and nim:\ncurl https://nim-lang.org/choosenim/init.sh -sSf | sh echo \u0026quot;export PATH=~/.nimble/bin:\\$PATH\u0026quot; \u0026gt;\u0026gt; ~/.bashrc export PATH=~/.nimble/bin:$PATH And we should have the Nim compiler in our path:\nubuntu@nim:~$ nim --version Nim Compiler Version 0.17.2 (2017-09-07) [Linux: amd64] Copyright (c) 2006-2017 by Andreas Rumpf git hash: 811fbdafd958443ddac98ad58c77245860b38620 active boot switches: -d:release Create a Nim program Link to heading Allright! Time to make a small Nim program called \u0026ldquo;moni\u0026rdquo; - don\u0026rsquo;t ask why. First create a directory to work in, obviously we should use git etc, but I leave that to you. We also run nimble init to get a skeleton of a so called .nimble file. Nimble is the \u0026ldquo;npm\u0026rdquo; of the Nim ecosystem. And a nimble file is similar to packages.json for npm.\nmkdir moni \u0026amp;\u0026amp; cd moni nimble init Now, let\u0026rsquo;s add some more lines to moni.nimble, starting with these three in the top section:\nbinDir = \u0026quot;bin\u0026quot; bin = @[\u0026quot;moni\u0026quot;] skipExt = @[\u0026quot;nim\u0026quot;] This tells nimble that this package produces binaries and will put them in the directory bin when building. We also tell it that we have a list of binaries, the syntax for a seq in Nim, which is a dynamic array, looks like @[ a, b, ... c ]. So we add \u0026quot;moni\u0026quot; to that list, the executable\u0026rsquo;s name.\nFinally we also tell Nimble that when this package later is installed, skip installing all .nim files, since we are not making a Nim library, we only want the compiled executable to be installed.\nLet\u0026rsquo;s also add a dependency called docopt which is a really nice Nim library for parsing command line arguments, to the bottom list of dependencies:\nrequires \u0026quot;docopt\u0026quot; The full file should now look like this:\n# Package version = \u0026#34;0.1.0\u0026#34; author = \u0026#34;Göran Krampe\u0026#34; description = \u0026#34;A simple MQTT publisher tool.\u0026#34; license = \u0026#34;MIT\u0026#34; binDir = \u0026#34;bin\u0026#34; bin = @[\u0026#34;moni\u0026#34;] skipExt = @[\u0026#34;nim\u0026#34;] # Dependencies requires \u0026#34;nim \u0026gt;= 0.17.2\u0026#34; requires \u0026#34;docopt\u0026#34; Ok, and finally, let\u0026rsquo;s write some code. To begin with the program will just parse out arguments, and can show help, save this as moni.nim:\nimport docopt let help = \u0026#34;\u0026#34;\u0026#34; moni - A simple MQTT publisher tool. Usage: moni [-u username] [-p password] [-s mqtturl] \u0026lt;topic\u0026gt; \u0026lt;payload\u0026gt; moni (-h | --help) moni (-v | --version) Options: -u username Set username [default: test]. -p password Set password [default: test]. -s mqtturl Set URL for the MQTT server [default: tcp://localhost:1883] -h --help Show this screen. -v --version Show version. \u0026#34;\u0026#34;\u0026#34; var args = docopt(help, version = \u0026#34;0.1.0\u0026#34;) # Get parameters let username = $args[\u0026#34;-u\u0026#34;] let password = $args[\u0026#34;-p\u0026#34;] let mqtturl = $args[\u0026#34;-s\u0026#34;] let topic = $args[\u0026#34;\u0026lt;topic\u0026gt;\u0026#34;] let payload = $args[\u0026#34;\u0026lt;payload\u0026gt;\u0026#34;] echo \u0026#34;Username: \u0026#34; \u0026amp; $username echo \u0026#34;Password: \u0026#34; \u0026amp; $password echo \u0026#34;Server: \u0026#34; \u0026amp; $mqtturl echo \u0026#34;Topic: \u0026#34; \u0026amp; $topic echo \u0026#34;Payload: \u0026#34; \u0026amp; $payload quit Time to compile it!\nIf we want nimble to suck down dependencies automatically for us, then we build using nimble, it will use the moni.nimble to figure out what to do:\nnimble build And we can then run the binary:\n./bin/moni If we supply a topic and payload we can see default values for options:\n./bin/moni topic payload We can also compile the moni.nim file directly, simply using the nim compiler - but that would have failed initially since we didn\u0026rsquo;t have the docopt dependency installed. But do try it now:\nnim c moni.nim The nim compiler will however put the binary in your current directory, not in bin.\nOk, let\u0026rsquo;s get serious and add some real MQTT code into this. First add a dependency in moni.nimble to the Nim wrapper of the PAHO MQTT C library, by adding the following line at the bottom of moni.nimble:\nrequires \u0026quot;https://github.com/barnybug/nim-mqtt\u0026quot; So with nimble we can require using direct URLs to git or mercurial repositories as well, we are not limited to the pulished known packages in the Nimble catalog. Then make the code look like this instead:\nimport docopt, mqtt, MQTTClient let help = \u0026#34;\u0026#34;\u0026#34; moni - A simple MQTT publisher tool. Usage: moni [-u username] [-p password] [-s mqtturl] \u0026lt;topic\u0026gt; \u0026lt;payload\u0026gt; moni (-h | --help) moni (-v | --version) Options: -u username Set username [default: test]. -p password Set password [default: test]. -s mqtturl Set URL for the MQTT server [default: tcp://localhost:1883] -h --help Show this screen. -v --version Show version. \u0026#34;\u0026#34;\u0026#34; var args = docopt(help, version = \u0026#34;0.1.0\u0026#34;) # Get parameters let username = $args[\u0026#34;-u\u0026#34;] let password = $args[\u0026#34;-p\u0026#34;] let mqtturl = $args[\u0026#34;-s\u0026#34;] let topic = $args[\u0026#34;\u0026lt;topic\u0026gt;\u0026#34;] let payload = $args[\u0026#34;\u0026lt;payload\u0026gt;\u0026#34;] # Print them echo \u0026#34;Username: \u0026#34; \u0026amp; $username echo \u0026#34;Password: \u0026#34; \u0026amp; $password echo \u0026#34;Server: \u0026#34; \u0026amp; $mqtturl echo \u0026#34;Topic: \u0026#34; \u0026amp; $topic echo \u0026#34;Payload: \u0026#34; \u0026amp; $payload const ClientId = \u0026#34;nim-mqtt-pub\u0026#34; proc connect(username, password, mqtturl: string): MQTTClient = ## Connect to MQTT server result = newClient(mqtturl, ClientId, MQTTPersistenceType.None) var connectOptions = newConnectOptions() connectOptions.username = username connectOptions.password = password result.connect(connectOptions) proc disconnect(client: MQTTClient) = ## Disconnect the client client.disconnect(1000) client.destroy() proc publish(client: MQTTClient, topic, payload: string) = ## Publish a payload on a topic discard client.publish(topic, payload, QOS.AtMostOnce, false) try: var client = connect(username, password, mqtturl) client.publish(topic, payload) client.disconnect() echo \u0026#34;Payload sent\u0026#34; except MQTTError: quit(\u0026#34;MQTT exception: \u0026#34; \u0026amp; getCurrentExceptionMsg(), QuitFailure) quit(QuitSuccess) A few quick remarks about the code:\nWhen you see $something, that\u0026rsquo;s Nim\u0026rsquo;s way of saying something.toString() When you see \u0026amp; that\u0026rsquo;s string concatenation. You also see three procs that we later call inside the try: block. A proc is just another name for function. In the connect proc there is a variable called result. It\u0026rsquo;s an implicit variable available in all procs that have a return value and represents the thing that will be returned. In the publish proc we see the discard statement, it\u0026rsquo;s used to \u0026ldquo;throw away\u0026rdquo; return values that we ignore, it has to be done explicitly in Nim or the compiler will complain. If all goes well we quit with success, otherwise with the exception message and failure . Then we build again:\nnimble build And let\u0026rsquo;s try running it aginst a public demo broker:\n./bin/moni -s tcp://broker.hivemq.com:1883 sensor/99 '{\u0026quot;temp\u0026quot;: 25.4, \u0026quot;flow\u0026quot;: 0.7}' could not load: libpaho-mqtt3c.so compile with -d:nimDebugDlOpen for more information Oops! Ok, so the MQTT wrapper library needs the C library of course! And it\u0026rsquo;s not available as a deb, so let\u0026rsquo;s get our hands dirty:\nsudo apt install libssl-dev make Then we can build and install Paho C from source:\ncd ~ git clone https://github.com/eclipse/paho.mqtt.c.git cd paho.mqtt.c make sudo make install sudo ldconfig Let\u0026rsquo;s try building again:\ncd ~/moni nimble build And finally we can hopefully publish via MQTT, let\u0026rsquo;s try it once more:\n./bin/moni -s tcp://broker.hivemq.com:1883 cucumber/99 \u0026#39;{\u0026#34;temp\u0026#34;: 25.4, \u0026#34;flow\u0026#34;: 0.7}\u0026#39; If it ends with \u0026ldquo;Payload sent\u0026rdquo; we are all good! We just sent a JSON payload to the cucumber/99 topic.\nHiveMQ accepts anonymous connections on the test broker so we don\u0026rsquo;t need to specify username/password. In order to verify that the above actually worked, you can point your browser to http://www.hivemq.com/demos/websocket-client/ and connect on port 8000 to broker.hivemq.com, then add topic subscription to \u0026ldquo;cucumber/#\u0026rdquo; and run the above command once more. If all works you should see the message appear!\nNow, to round things off we can install this little program too, locally for your user inside the LXC container that is. :) You just run nimble install and then we have it in our path.\nOk, that\u0026rsquo;s all folks - you are now a Nim hacker!\n"},{"title":"Benchmarking Spry vs Squeak","permalink":"https://goran.krampe.se/2016/08/26/benchmarking-spry-vs-squeak/","summary":"\u003cp\u003e\u003ca href=\"http://sprylang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSpry\u003c/a\u003e\n is evolving quite nicely during my night hours. Focusing on performance is however still premature, but I do want to verify that I am not barking up the wrong tree, like \u0026hellip; in the wrong forest even. So I make trivial benchmarks from time to time, just to see and learn.\u003c/p\u003e\n\u003cp\u003eSome background on the Spry implementation may be interesting. Spry is implemented in Nim as a \u003cstrong\u003edirect AST interpreter\u003c/strong\u003e, it\u0026rsquo;s not a JIT, in only about 2000 lines of code. It has a \u003cstrong\u003erecursive classic \u0026ldquo;naive\u0026rdquo; design\u003c/strong\u003e and uses a \u003cstrong\u003espaghetti stack of activation records\u003c/strong\u003e, all allocated on the heap relying fully on Nim\u0026rsquo;s GC to do it\u0026rsquo;s work. It also relies on Nim\u0026rsquo;s method \u003cstrong\u003edynamic dispatch\u003c/strong\u003e in the interpreter loop for dispatching on the different AST nodes. Blocks are true closures and control structures like \u003ccode\u003etimesRepeat:\u003c/code\u003e are implemented as primitives, normally \u003cstrong\u003enot cheating\u003c/strong\u003e. Suffice to say, there are LOTS of things we can do to make Spry run faster!\u003c/p\u003e\n\u003cp\u003eThe philosophy of implementation is to keep Spry very small and \u0026ldquo;shallow\u0026rdquo; which means we rely as much as possible on the shoulders of others. In this case, primarily Nim and it\u0026rsquo;s superb features, performance and standard library.\u003c/p\u003e\n\u003cp\u003eEnough jibbering, let\u0026rsquo;s do some silly damn lies - ehrm, I mean silly tests!\u003c/p\u003e","content":"Spry is evolving quite nicely during my night hours. Focusing on performance is however still premature, but I do want to verify that I am not barking up the wrong tree, like \u0026hellip; in the wrong forest even. So I make trivial benchmarks from time to time, just to see and learn.\nSome background on the Spry implementation may be interesting. Spry is implemented in Nim as a direct AST interpreter, it\u0026rsquo;s not a JIT, in only about 2000 lines of code. It has a recursive classic \u0026ldquo;naive\u0026rdquo; design and uses a spaghetti stack of activation records, all allocated on the heap relying fully on Nim\u0026rsquo;s GC to do it\u0026rsquo;s work. It also relies on Nim\u0026rsquo;s method dynamic dispatch in the interpreter loop for dispatching on the different AST nodes. Blocks are true closures and control structures like timesRepeat: are implemented as primitives, normally not cheating. Suffice to say, there are LOTS of things we can do to make Spry run faster!\nThe philosophy of implementation is to keep Spry very small and \u0026ldquo;shallow\u0026rdquo; which means we rely as much as possible on the shoulders of others. In this case, primarily Nim and it\u0026rsquo;s superb features, performance and standard library.\nEnough jibbering, let\u0026rsquo;s do some silly damn lies - ehrm, I mean silly tests!\n| b r | b := OrderedCollection new. r := Random new. 2000000 timesRepeat: [b add: (r nextInt: 10)]. [b select: [:x | x \u0026gt; 8]] timeToRun The above snippet runs in around 40 ms in latest Squeak 5.1. Nippy indeed! Ok, so in Spry then with a recently added primitive for select::\nb = [] 2000000 timesRepeat: [b add: (10 random)] [b select: [:x \u0026gt; 8]] timeToRun First of all, if this is the first Spry code you have seen, I hope you can tell it\u0026rsquo;s Smalltalk-ish and it\u0026rsquo;s even shorter. :) A few notes to make it clearer:\nWe don\u0026rsquo;t declare local variable names in Spry. Assignment uses = and equality uses ==, no big reason, just aligning slightly with other languages. [] is the syntax for creating a Block (at parse time), which is the workhorse dynamic array (and code block), like an OrderedCollection. Spry has no statement separators (!) so no . at the end, nor does it rely on line endings or indentation, same snippet can be written exactly the same on a single line. You need (currently) a tad more parentheses in Spry code, for example we need (10 random) because Spry evaluates strictly from left to right. Blocks don\u0026rsquo;t declare variables either, they are \u0026ldquo;pulled in\u0026rdquo; using the syntax :foo. So blocks are often shorter than in Smalltalk like [:x \u0026gt; 8] or even [:a \u0026lt; :b]. Spry runs this in 1000 ms, not that shabby, but of course about 25x slower than Squeak. However\u0026hellip; I think I can double the Spry speed and if so, then we are in \u0026ldquo;can live with that-country\u0026rdquo;.\nJust to prove Spry is just as dynamic and cool as Smalltalk (even more so actually in many parts), we can also implement select: in Spry itself (and for the more savvy out there, yes, detect: can also be implenented using the same non local return trick as Smalltalk uses):\nspryselect: = method [:pred result = ([] clone) self reset [self end?] whileFalse: [ n = (self next) do pred n then: [result add: n]] ^result] Without explaining that code, how fast is the same test using this variant implemented in Spry itself? 8.8 seconds, not horrible, but\u0026hellip; I think we prefer the primitive :)\nNow\u0026hellip; let\u0026rsquo;s pretend this particular case is an important bottleneck in our 20 million dollar project. We just need to be faster! The Spry strategy is then to drop down to Nim and make a primitive that does everything in Nim. Such a 7-line primitive could look like this:\nnimMeth(\u0026#34;selectLarger8\u0026#34;): # evalArgInfix(spry) pulls in the receiver on the left. # We convert it to the type we expect - SeqComposite is a super type # of Block, Paren, Curly. let self = SeqComposite(evalArgInfix(spry)) # We create a new empty Block to put the selected nodes in. let returnBlok = newBlok() # We perform a regular Nim iteration. self.nodes is a Nim seq[Node]. for each in self.nodes: # For each element we convert to IntVal, which is the node type for a Spry int. # This will cause a catchable exception if it\u0026#39;s not an IntVal. if IntVal(each).value \u0026gt; 8: returnBlok.add(each) # A primitive always returns a Node or subclass thereof, like in this case a Blok. return returnBlok Then it runs in 10 ms!\nYup, it\u0026rsquo;s cheating, but the 20 million dollar project wouldn\u0026rsquo;t care\u0026hellip; The thing to realize here is that its MUCH easier to cheat in Spry than it is in Squeak/Pharo. But\u0026hellip; yes, you would need to know how to make a primitive, and as a primitive it\u0026rsquo;s compiled code so you can\u0026rsquo;t mess with it live, and it also presumes that each node is an IntVal. However, Spry (when I fix error handling) should gracefully handle if it isn\u0026rsquo;t an IntVal, that will trigger a Nim exception that the Spry interpreter should catch.\nIf you have made primitives in Squeak/Pharo you know it\u0026rsquo;s much more complicated. You need to take great care with allocation since the GC can move things under your feet. You must convert things to C and so on, and building the stuff is messy. Spry on the other hand shares the underlying data structures with Nim. In other words, Spry nodes are Nim objects. It\u0026rsquo;s trivial to work with them, allocate new ones like newBlok() above creates a new block and so on. This is a huge deal! Recently when I started integrating libui with Spry (a pretty slick movie) I got callbacks from libui back into Spry working in like\u0026hellip; 30 minutes of thinking. That\u0026rsquo;s HUGE! Doing callbacks from C or C++ back into Squeak has been a really messy and complicated thing for YEARS. Not sure if it\u0026rsquo;s any better.\nAlso, going pure Nim would be much faster still since it would use a seq[int] and not a seq[Node] (boxed ints) - a vast difference. So if we really wanted to work with large blocks of integers, a special such node type could easily be made that exposes primitives for it. Kinda like the FloatArray thing in Squeak, etc.\nString finding Link to heading Let\u0026rsquo;s look at another example where Spry actually beats Squeak. And by beat I mean really beat, by factor 4x! The test is to use findString:startingAt: in a fairly large string, to find a match, 2 million times.\n| s time | \u0026#34;A file with a mixed text 15712 bytes, hit is at 11499, 6 partial hits before that.\u0026#34; s := (StandardFileStream oldFileNamed: \u0026#39;string.txt\u0026#39;) contentsOfEntireFile. time := [2000000 timesRepeat: [ s findString: \u0026#39;native threads and super high performance garbage\u0026#39; startingAt: 12 ]] timeToRun This snippet runs in 135 seconds in Squeak 5.1. The corresponding Spry code is:\n# A file with a mixed text 15712 bytes, hit is at 11499, 6 partial hits before that. s = readFile \u0026#34;string.txt\u0026#34; time = ([2000000 timesRepeat: [ s findString: \u0026#34;native threads and super high performance garbage\u0026#34; startingAt: 12 ]] timeToRun) Again, note how Smalltalkish the code looks - and \u0026hellip; you know, come on Smalltalk\u0026hellip; reading a file? It shouldn\u0026rsquo;t need to be (StandardFileStream oldFileNamed: 'string.txt') contentsOfEntireFile for such a common and mundane task!\nYou gotta admit, readFile \u0026quot;string.txt\u0026quot; is nicer. But hey, says the careful reader, what the heck is that? Yes, Spry supports \u0026ldquo;prefix functions\u0026rdquo; that take arguments from the right, Rebol style. It isn\u0026rsquo;t used much in Spry code, but for some things it really reads better. For example, in Spry we do echo \u0026quot;hey\u0026quot; instead of Transcript show: 'hey'. That\u0026rsquo;s another thing that is overly verbose in Smalltalk and should IMHO be fixed, at least just to save poor newbies their fingers. Anyway (end of rant)\u0026hellip;.\n\u0026hellip;Spry runs that in 33 seconds! And just to get a sense for how large the primitive is in Spry, it\u0026rsquo;s exactly 5 lines of code:\nnimMeth(\u0026#34;findString:startingAt:\u0026#34;): let self = StringVal(evalArgInfix(spry)).value let sub = StringVal(evalArg(spry)).value let start = IntVal(evalArg(spry)).value newValue(find(self, sub, start)) It\u0026rsquo;s quite easy to follow. We just pull in arguments and unbox them into Nim string, int, int - and then we call Nim\u0026rsquo;s find and we finish by using newValue() to box the answer as a Spry IntVal again. This shows how easily - no\u0026hellip; trivially we can map Spry behaviors to Nim library code which runs at the speed of C/C++.\nSpeeding up Spry Link to heading Given all this, it would still be nice to improve Spry to come say \u0026hellip; within 10x of Cog for general code, perhaps in this case shave it down from 1000 ms to around 300 ms. The things that I do know I should do to improve speed in general are the following:\nFormalize binding phase in Spry. This means caching the binding of words \u0026ldquo;in place\u0026rdquo;, especially words resolving to funcs and methods. This would eliminate a HUGE amount of idiotic lookups that Spry currently performs every time it runs a block or function and profiles have already shown that this is priority UNO to fix since it alone usually eats 50% of runtime. Move to a stackless design of the interpreter. Exactly what performance improvement this would give, I am not sure. But it would remove the growing intertwined C stack and enable things like Spry stack manipulations, continuations, coroutines etc, so we really want it! Profile the interpreter to see what low hanging fruit exists after the above. :) I hope this got you interested in Spry!\n"},{"title":"Is Spry a Smalltalk?","permalink":"https://goran.krampe.se/2016/07/19/is-spry-a-smalltalk/","summary":"\u003cp\u003eI love \u003ca href=\"http://world.st\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSmalltalk\u003c/a\u003e\n and I have been in love with it since approximately 1994. I have used VisualWorks, VisualAge (IBM Smalltalk), Dolphin Smalltalk, GemStone, \u003ca href=\"http://squeak.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSqueak\u003c/a\u003e\n and \u003ca href=\"http://pharo.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ePharo\u003c/a\u003e\n quite a lot, and I was very active in the Squeak community for a long period.\u003c/p\u003e\n\u003cp\u003eBut the last few years, finally, I have started to feel the \u0026ldquo;burn\u0026rdquo;\u0026hellip; as in \u003ca href=\"http://gagne.homedns.org/~tgagne/contrib/EarlyHistoryST.html#29\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u0026ldquo;Let\u0026rsquo;s burn our disk packs!\u0026rdquo;\u003c/a\u003e\n. And last year I started doing something about it - and the result is \u003ca href=\"http://sprylang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSpry\u003c/a\u003e\n. Spry is only at version 0.break-your-hd and several key parts are still missing, but its getting interesting already.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eNow\u0026hellip; is Spry a Smalltalk? And what would that even mean?\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eI think the reason I am writing this article is because I am feeling a slight frustration that not more people in the Smalltalk community find Spry interesting. :)\u003c/p\u003e\n\u003cp\u003eAnd sure, who am I to think Spry is anything remotely interesting\u0026hellip; but I would have loved more interest. It may of course change when Spry starts being useful\u0026hellip; or perhaps the lack of interest is because it\u0026rsquo;s not \u0026ldquo;a Smalltalk\u0026rdquo;?\u003c/p\u003e\n\u003ch2 id=\"smalltalk-family\"\u003e\n  Smalltalk family\n  \u003ca class=\"heading-link\" href=\"#smalltalk-family\"\u003e\n    \u003ci class=\"fa-solid fa-link\" aria-hidden=\"true\" title=\"Link to heading\"\u003e\u003c/i\u003e\n    \u003cspan class=\"sr-only\"\u003eLink to heading\u003c/span\u003e\n  \u003c/a\u003e\n\u003c/h2\u003e\n\u003cp\u003eThe Smalltalk family of languages has a fair bit of variation, for example \u003ca href=\"http://www.selflanguage.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSelf\u003c/a\u003e\n is clearly in this family, although it doesn\u0026rsquo;t even have classes, but it maintains a similar \u0026ldquo;feel\u0026rdquo; and shares several Smalltalk \u0026ldquo;values\u0026rdquo;. There have been a lot of Smalltalks over the years, even at PARC they made different variants before releasing Smalltalk-80.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eSo\u0026hellip; if we look at Spry, can it be considered a member of the Smalltalk family?\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eThere is an \u003ca href=\"http://wiki.squeak.org/squeak/172\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eANSI standard\u003c/a\u003e\n of Smalltalk - but not many people care about it, except for some vendors perhaps. I should note however that \u003ca href=\"http://www.seaside.st\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSeaside\u003c/a\u003e\n apparently (I think) has brought around a certain focus on the ANSI standard since every Smalltalk implementation on earth wants to be able to run Seaside and Seaside tries to enforce relying on the ANSI standard (correct me if I am wrong).\u003c/p\u003e\n\u003cp\u003eMost Smalltalk implementations share a range of characteristics, and a lot of them also follow the ANSI standard, but they can still differ on pretty major points.\u003c/p\u003e\n\u003cp\u003eMy \u003cstrong\u003epersonal take\u003c/strong\u003e on things in Smalltalk that are pretty darn important and/or unique are:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eEverything is an object including meta levels\u003c/li\u003e\n\u003cli\u003eA solid model for object oriented programming\u003c/li\u003e\n\u003cli\u003eThe image model\u003c/li\u003e\n\u003cli\u003e100% live system\u003c/li\u003e\n\u003cli\u003eThe browser based IDE with advanced cross referencing, workspaces and debuggers\u003c/li\u003e\n\u003cli\u003eThe keyword syntax and message cascades\u003c/li\u003e\n\u003cli\u003eMessage based execution model\u003c/li\u003e\n\u003cli\u003eDynamic typing and polymorphism\u003c/li\u003e\n\u003cli\u003eClosures everywhere with lightweight syntax and non local return\u003c/li\u003e\n\u003cli\u003eVery capable Collections and a good standard library\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eNot all Smalltalks cover all 10. For example, there are several Smalltalks without the image model and without a browser based IDE. Self and Slate and other prototypical derivatives don\u0026rsquo;t have classes. Some Smalltalks have much less evolved class libraries for sure, and some are more shallow in the \u0026ldquo;turtle department\u0026rdquo;.\u003c/p\u003e\n\u003cp\u003eIn Spry we are deviating on a range of these points, but we are also definitely \u003cstrong\u003ematching some\u003c/strong\u003e of them!\u003c/p\u003e","content":"I love Smalltalk and I have been in love with it since approximately 1994. I have used VisualWorks, VisualAge (IBM Smalltalk), Dolphin Smalltalk, GemStone, Squeak and Pharo quite a lot, and I was very active in the Squeak community for a long period.\nBut the last few years, finally, I have started to feel the \u0026ldquo;burn\u0026rdquo;\u0026hellip; as in \u0026ldquo;Let\u0026rsquo;s burn our disk packs!\u0026rdquo; . And last year I started doing something about it - and the result is Spry . Spry is only at version 0.break-your-hd and several key parts are still missing, but its getting interesting already.\nNow\u0026hellip; is Spry a Smalltalk? And what would that even mean?\nI think the reason I am writing this article is because I am feeling a slight frustration that not more people in the Smalltalk community find Spry interesting. :)\nAnd sure, who am I to think Spry is anything remotely interesting\u0026hellip; but I would have loved more interest. It may of course change when Spry starts being useful\u0026hellip; or perhaps the lack of interest is because it\u0026rsquo;s not \u0026ldquo;a Smalltalk\u0026rdquo;?\nSmalltalk family Link to heading The Smalltalk family of languages has a fair bit of variation, for example Self is clearly in this family, although it doesn\u0026rsquo;t even have classes, but it maintains a similar \u0026ldquo;feel\u0026rdquo; and shares several Smalltalk \u0026ldquo;values\u0026rdquo;. There have been a lot of Smalltalks over the years, even at PARC they made different variants before releasing Smalltalk-80.\nSo\u0026hellip; if we look at Spry, can it be considered a member of the Smalltalk family?\nThere is an ANSI standard of Smalltalk - but not many people care about it, except for some vendors perhaps. I should note however that Seaside apparently (I think) has brought around a certain focus on the ANSI standard since every Smalltalk implementation on earth wants to be able to run Seaside and Seaside tries to enforce relying on the ANSI standard (correct me if I am wrong).\nMost Smalltalk implementations share a range of characteristics, and a lot of them also follow the ANSI standard, but they can still differ on pretty major points.\nMy personal take on things in Smalltalk that are pretty darn important and/or unique are:\nEverything is an object including meta levels A solid model for object oriented programming The image model 100% live system The browser based IDE with advanced cross referencing, workspaces and debuggers The keyword syntax and message cascades Message based execution model Dynamic typing and polymorphism Closures everywhere with lightweight syntax and non local return Very capable Collections and a good standard library Not all Smalltalks cover all 10. For example, there are several Smalltalks without the image model and without a browser based IDE. Self and Slate and other prototypical derivatives don\u0026rsquo;t have classes. Some Smalltalks have much less evolved class libraries for sure, and some are more shallow in the \u0026ldquo;turtle department\u0026rdquo;.\nIn Spry we are deviating on a range of these points, but we are also definitely matching some of them!\nHow Spry stacks up Link to heading Everything is an object including meta levels. No, in Spry everything is an AST node, not an object. A similar feel of uniformity exists, but it\u0026rsquo;s different. A solid model for object oriented programming. Yes I think so, but Spry does not use the classic class model but is experimenting with a functional OO model. The image model. No, not yet. But the idea is to have it, not on a binary \u0026ldquo;memory snapshot\u0026rdquo; level, but in a more fine granular way. 100% live system. Yes, Spry is definitely 100% live and new code is created by running code etc. The browser based IDE with advanced cross referencing, workspaces and debuggers. No, but eventually I hope Spry gets something similar. First step is making a UI binding and evolving the meta programming mechanisms. The keyword syntax and message cascades. Yes, Spry has keyword syntax, but also has prefix syntax and currently no cascades nor statement separators. Message based execution model. No, Spry execution is not message based, but rather functional in nature. The practical difference should be slim to none I hope. Dynamic typing and polymorphism. Yes, Spry is dynamically typed and offers polymorphism, but through a different technique. Closures everywhere with lightweight syntax and non local return. Yes, closures with non local return, similar pervasiness, even more light weight syntax than Smalltalk! Very capable Collections and a good standard library. No, not yet. But intend to have it and will in many ways try to pick the best from Smalltalk and Nim. So Spry scores 5/10. Not that shabby! And I am aiming for 3 more (#3, #5, #10) getting us up to 8/10. The two bullets that I can\u0026rsquo;t really promise are #1 and #7, but I hope the alternative approach in Spry for these two bullets still reaches similar effects.\nLet\u0026rsquo;s look at #1, #2 and #6 in more detail. The other bullets can also be discussed, but \u0026hellip; not in this article :)\nEverything is an object including meta levels Link to heading In Smalltalk everything is an object, there are no \u0026ldquo;fundamental datatypes\u0026rdquo;. Every little thing is an instance of a class which makes the language clean and powerful. There are typically some things that the VM treats differently under the hood, like SmallInteger and BlockClosure etc, but the illusion is quite strong.\nSpry on the other hand was born initially as a \u0026ldquo;Rebol incarnation\u0026rdquo; and evolved towards Smalltalk given my personal inclination. Rebol as well as Spry is homoiconic and when I started building Spry it felt very natural to simple let the AST be the fundamental \u0026ldquo;data is code and code is data\u0026rdquo; representation. This led to the atomic building block in Spry being the AST Node. So everything is an AST node (referred to as simply \u0026ldquo;node\u0026rdquo; hence on), but there are different kinds of nodes especially for various fundamental datatypes like string, int and float and they are explicitly implemented in the VM as \u0026ldquo;boxed\u0026rdquo; Nim types.\nIn Smalltalk objects imply that we can refer to them and pass them around, they have a life cycle and are garbage collected, they have an identity and they are instanciated from classes which describes what messages I can send to them.\nIn Spry the same things apply for nodes, except that they are not instanciated from classes. Instead nodes are either created by the parser through explicit syntax in the parse phase, or they are created during evaluation by cloning already existing ones.\nAn interesting aspect of Spry\u0026rsquo;s approach is that we can easily create new kinds of nodes as extensions to the Spry VM. And these nodes can fall back on types in the Nim language that the VM is implemented in. This means we trivally can reuse the math libraries, string libraries and so on already available in Nim! In essence - the Spry VM and the Spry language is much more integrated with each other and since the VM is written in Nim, Nim and Spry live in symbiosis.\nUsing Spry it should be fully normal and easy to extend and compile your own Spry VM instead of having to use a downloaded binary VM or learning Black Magic in order to make a plugin to it, as it may feel in the Squeak/Pharo world.\nFinally, just as with Smalltalk the meta level is represented and manipulated using the same abstractions as the language offers.\nConlusion? Spry is different but reaches something very similar in practice.\nA solid model for object oriented programming Link to heading But what kind of behaviors are associated with a particular node then? In Spry I am experimenting with a model where all nodes can be tagged and these tags are the basis for polymorphism and dynamic function lookup. You can also avoid tagging and simply write regular functions and call them purely by name, making sure you feed them with the right kind of nodes as arguments, then we have a pure functional model with no dynamic dispatch being performed.\nIn Spry we have specific node types for the fundamental datatypes int, float, string and a few other things. But for \u0026ldquo;normal\u0026rdquo; objects that have instance variables we \u0026ldquo;model objects as Maps\u0026rdquo;. JavaScript is similar, it has two fundamental composition types - the \u0026ldquo;array\u0026rdquo; and the \u0026ldquo;object\u0026rdquo; which works like a Map. In Spry we also have these two basic structures but we call them Block and Map. This means we can model an object using a Map, we don\u0026rsquo;t declare instance variables - we just add them dynamically by name to the map.\nBut just being a Map doesn\u0026rsquo;t make an object - because it doesn\u0026rsquo;t have any behaviors associated with it! In Smalltalk objects know their class which is the basis for behavior dispatch and in Spry I am experimenting with opening up that attribute for more direct manipulation, a concept I call tags:\nAny node can be tagged with one or more tags. Functions are also nodes and can thus also be tagged. A polyfunc is a composite function with sub functions. A polyfunc selects which sub function to evaluate based on comparing tags for the first argument, the \u0026ldquo;receiver\u0026rdquo; with the tags for the sub functions. The net effect of this is that we end up with a very flexible model of dispatch. This style of overloading is a tad similar to structural pattern matching in Erlang/Elixir.\nOne can easily mimic a class by associating a bunch of functions with a specific tag. The tags on a node have an ordering, this means we also get the inheritance effect where we can inherit a bunch of functions (by adding a tag for them) and then override a subset using another tag - by putting that tag first in the tag collection of the node. Granted this is all experimental and we will see how it plays out. It does however have a few interesting advantages over class based models:\nTags are dynamic and can be added/removed/reordered during the life cycle of an object. Tags have no intrinsic relations to each other, thus multiple inheritance in various ways works fine. Polyfuncs are composed dynamically which makes it easy to extend existing modules with new behaviors (like class extensions in Smalltalk). I am just starting to explore how this works, so the jury is still out.\nThe keyword syntax and message cascades Link to heading Spry supports infix and prefix functions and additionally keyword syntax using a simple parsing transformation. The following variants are available:\n# Function call with zero arguments. # Well, we are in fact referring to whatever is bound to the name \u0026#34;root\u0026#34; # and evaluating it - and if it is indeed a func then it will be called. # This happens to be a Spry primitive func that returns the Map holding the # root bindings, essentially the same as \u0026#34;Smalltalk\u0026#34; in Smalltalk. root # Prefix function call with one argument. echo \u0026#34;Hey\u0026#34; # Prefix function call with two arguments. I am experimenting with different # styles of conditionals in Spry, Smalltalk style is also doable. if (3 \u0026lt; 4) [echo \u0026#34;yes\u0026#34;] # Infix function call with one argument. [1 2 3] size # Infix function call with two arguments. In Spry this is currently not limited # to a specific subset of characters like binary messages in Smalltalk. 3 + 4 # Infix function call with three arguments, keyword style. # Parser rewrites this as \u0026#34;[1] at:put: 0 2\u0026#34; and since \u0026#34;:\u0026#34; is a valid character # in a Spry name, it will simply run that func. [1] at: 0 put: 2 # Infix function calls with 3 or more arguments do not need to use keyword style though, # foo here could be an infix function taking 4 arguments. Not good style though. 1 foo 3 4 5 # Keyword style can be used for prefix functions too so # that there is no receiver on the left! Looks funky for a Smalltalker and I # am not yet certain it is a good idea. loadFile: \u0026#34;amodule.sy\u0026#34; This means Spry supports the classic Smalltalk messge syntax (unary, binary, keyword) in addition to prefix syntax which sometimes is quite natural, like for echo. Currently there is no syntactic support for cascades, but I am not ruling out the ability to introduce something like it down the road.\nConclusion Link to heading Spry is very different from Smalltalk and I wouldn\u0026rsquo;t call it \u0026ldquo;a Smalltalk\u0026rdquo;, but rather \u0026ldquo;Smalltalk-ish\u0026rdquo;. I hope Spry can open up new exciting programming patterns and abilities we haven\u0026rsquo;t seen yet in Smalltalk country.\nHope you like it!\n"},{"title":"Fowltalk - a new Smalltalk","permalink":"https://goran.krampe.se/2016/06/19/fowltalk/","summary":"\u003cp\u003eIn my quest making \u003ca href=\"http://sprylang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSpry\u003c/a\u003e\n I also learned about other efforts in the Nim community to construct Smalltalk-like dynamic languages. The most ambitious one may be \u003ca href=\"https://bitbucket.org/fowlmouth/idk\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eFowltalk\u003c/a\u003e\n by \u0026ldquo;fowl\u0026rdquo; who typically hangs out in the #nim channel on Freenode. Fowltalk started out written in Nim but since fowl wanted to learn more C++ it\u0026rsquo;s now written in C++17.\u003c/p\u003e\n\u003cp\u003eAt the moment he is rewriting the parser and code generator parts \u003ca href=\"https://bitbucket.org/fowlmouth/idk/src/2623f1e366d9a77f08feceda549bf0d9b3b9a72b/bootstrap.1?fileviewer=file-view-default\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ein the language itself\u003c/a\u003e\n, following a similar bootstrapping style as \u003ca href=\"http://piumarta.com/software/cola/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eIan Piumarta\u0026rsquo;s idst\u003c/a\u003e\n. For example, here is \u003ca href=\"https://bitbucket.org/fowlmouth/idk/src/2623f1e366d9a77f08feceda549bf0d9b3b9a72b/bootstrap.1?fileviewer=file-view-default#bootstrap.1-483\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ethe method parsing keyword messages\u003c/a\u003e\n.\u003c/p\u003e","content":"In my quest making Spry I also learned about other efforts in the Nim community to construct Smalltalk-like dynamic languages. The most ambitious one may be Fowltalk by \u0026ldquo;fowl\u0026rdquo; who typically hangs out in the #nim channel on Freenode. Fowltalk started out written in Nim but since fowl wanted to learn more C++ it\u0026rsquo;s now written in C++17.\nAt the moment he is rewriting the parser and code generator parts in the language itself , following a similar bootstrapping style as Ian Piumarta\u0026rsquo;s idst . For example, here is the method parsing keyword messages .\nAt the moment Fowltalk is nowhere near usefulness but its fun stuff!\nIt\u0026rsquo;s interesting to look at these bootstrap* files - we can immediately notice some syntactic differences to Smalltalk-80:\nBlock arguments are written like [| :x :y | ... ] and you can mix both locals and params there: [| :aParam aLocalHasNoColon | ... ]. Instinctively I can agree with the combination, but I would probably then make the first | optional.\nSome messages have been changed, like ifTrue:ifFalse: is instead ifTrue:else:. I have done similar simplifications in Spry. And just like in Spry ivars are referenced using @myIvar.\nThere isn\u0026rsquo;t any documentation on Fowltalk yet, but it\u0026rsquo;s clearly a rather elaborate implementation. It compiles to bytecodes, uses numbered primitives (I think) and there is an image mechanism.\nIt was also quite easy to get the REPL up and running, but just as with Spry, it\u0026rsquo;s hard to know how to use it! On Ubuntu I installed boost sudo apt-get install libboost1.58-dev and then it was easy to get it running following the instructions, as long as you change setup-linenoise.sh to setup_linenoise.sh.\nThe image constructed by the bootstrap process is 67Mb in size. Then we can do the canonical Smalltalk test in the REPL:\ngokr@yoda:~/fowltalk/idk$ ./bin/oop -i oop.img --mmap --repl \u0026gt; (3 + 4) print 7 \u0026gt; !quit gokr@yoda:~/fowltalk/idk$ Fowl mentioned that the new parser can be loaded using !read bootstrap.1 but\u0026hellip; at the moment that causes errors.\nIt will be interesting to see where this goes! Fowltalk is very early in its evolution, and it\u0026rsquo;s not a JIT, but it\u0026rsquo;s a real bytecode VM with an image and we can never have enough Smalltalk-like languages! :)\n"},{"title":"Spry Performance","permalink":"https://goran.krampe.se/2016/05/24/spry-performance/","summary":"\u003cp\u003eWhen writing Spry I am so far mainly ignoring performance. The general execution of Spry code will be a regular interpreter (although stackless I hope) and not a JIT. But that doesn\u0026rsquo;t prevent us from playing around and learning something!\u003c/p\u003e\n\u003cp\u003eIn this article I do some silly experiments around interpreter startup time and fooling around with 40 million element arrays. As usual, I am fully aware that the languages (Pharo Smalltalk, NodeJS, Python) I compare with a) have lots of other ways to do things b) may not have been used exactly as someone else would have done it. A truck load of salt required. Now\u0026hellip; let\u0026rsquo;s go!\u003c/p\u003e\n\u003cimg src=\"/spry/thetruth.jpg\" alt=\"The\" style=\"display:block; margin:0 auto;\"\u003e","content":"When writing Spry I am so far mainly ignoring performance. The general execution of Spry code will be a regular interpreter (although stackless I hope) and not a JIT. But that doesn\u0026rsquo;t prevent us from playing around and learning something!\nIn this article I do some silly experiments around interpreter startup time and fooling around with 40 million element arrays. As usual, I am fully aware that the languages (Pharo Smalltalk, NodeJS, Python) I compare with a) have lots of other ways to do things b) may not have been used exactly as someone else would have done it. A truck load of salt required. Now\u0026hellip; let\u0026rsquo;s go!\nStartup time Link to heading Spry is pretty fast starting up which obviously has to do with Spry not doing much at all when starting :)\nSo a trivial hello world being run using hashbang, executed 1000 times from another bash script, takes substantially less time than the same in Python. Useful benchmark? Not really, but obviously we can do scripting with Spry and at least not paying much for startup times! Here are the two trivial scripts and the bash script running them 1000 times:\n#!/usr/bin/env spry echo \u0026#34;Hello world\u0026#34; #!/usr/bin/env python print \u0026#34;Hello World\u0026#34; #!/bin/bash # Run a trivial hashbang Spry script 1000 times for run in {1..1000} do ./hello.sy done If we run the above, first for hello.sy and then hello.py, as reported by time:\n# Spry real\t0m4.071s user\t0m0.740s sys\t0m0.428s # Python real\t0m13.812s user\t0m8.904s sys\t0m2.324s # Empty shell script for comparison real\t0m2.505s user\t0m0.024s sys\t0m0.176s Hum! So a trivial Spry script is 3-10x quicker depending on what you count (real clock vs cpu time etc), and\u0026hellip; no, it\u0026rsquo;s not output to stdout that is the issue, even a \u0026ldquo;silent\u0026rdquo; program that just concatenates \u0026ldquo;hello\u0026rdquo; with \u0026ldquo;world\u0026rdquo; suffers similarly in Python.\nWe can of course also compile this into a binary by embedding the Spry source code in a Nim program - it\u0026rsquo;s actually trival to do. The 5th line below could of course be a full script. Since the Spry interpreter is modular we can pick some base modules to include, in this case the IO module is needed for echo to work so we add it to the interpreter on line 3:\nimport spryvm, modules/spryio let spry = newInterpreter() spry.addIO() discard spry.eval \u0026#34;\u0026#34;\u0026#34;[ echo \u0026#34;Hello World\u0026#34; ]\u0026#34;\u0026#34;\u0026#34; ..and then we build a binary using nim c -d:release hello.nim and if we run that instead from the same bash loop we get:\nreal\t0m0.840s user\t0m0.028s sys\t0m0.096s Of course Python can do lots of similar tricks, so I am not making any claims! But still very neat. And oh, we didn\u0026rsquo;t even try comparing to Pharo here :) Startup times is definitely not a strength of Smalltalk systems in general, typically due to lack of minimal images etc.\n40 million ints Link to heading I wanted to create some fat collection and do some loops over it. Spry has a universal ordered collection called a Block. Smalltalk has it\u0026rsquo;s workhorse OrderedCollection. Nodejs has an Array. Let\u0026rsquo;s stuff one with 40 million integers and then sum them up!\nNOTE: The first numbers published were a bit off and I also realized an issue with Cog and LargeIntegers so this article is adjusted.\nPharo 4 with the Cog VM:\nPopulating the collection: 3 seconds Sum the collection using iteration: 15 seconds Populating the collection with 1s only: 2 seconds Sum the collection of 1s (staying within SmallInteger) using iteration: 0.6 seconds! NodeJS 4.4.1:\nPopulating the collection: 0.6 seconds! (weird! sometimes much slower) Sum the collection using iteration: 3 seconds Sum the collection using reduce: 1.2 seconds Python 2.7.10:\nPopulating the collection: 7 seconds Sum the collection using iteration: 4 seconds Sum the collection using interation with lambda: 4 seconds! Using sum function: 0.3 seconds! Spry:\nPopulating the collection: 72 seconds (cough) Sum the collection using iteration: 101 seconds (cough, cough) Spry with activation record reuse:\nPopulating the collection: 32 seconds (better) Sum the collection using iteration: 60 seconds (better) Ehum\u0026hellip;\nNOTES\nSo Cog kicks proverbial ass when not spilling into LargeIntegers! Impressed. NodeJS is fast, we know that, but Cog beats it on the iteration which was interesting. But NodejS populating in 0.6 seconds? Weird! Sometimes it took 10 seconds, it was almost like NodeJS had some odd \u0026ldquo;warm caching\u0026rdquo; going on. Spry\u0026hellip; is slow :) But a bit of activation record reuse definitely improved it by 2x. Python is definitely surprising me! Wow, especially populating in 7 seconds and summing with lambda in 4? Impressive. If we spend some time profiling Spry we can quickly conclude that the main bottleneck is the lack of a binding phase in Spry - or in other words - every time we run a block, we lookup all words! Unless I am reading the profile wrong I think the endless lookups make up almost half the execution time. So that needs fixing. And I also will move to a stackless interpreter down the line, and that should give us a bit more.\nAnd what about Python\u0026rsquo;s sum function that did it in whopping 0.3 seconds? Yep, definitely the way to go with an optimized primitive function for this, which brings me to\u0026hellip;\nSpry Secret Weapon Link to heading The secret weapon of Spry!\nOne core idea of Spry is to make a Smalltalk-ish language with its inner machinery implemented in Nim using Nim data types. So the collection work horse in Spry, the block is just a Nim seq under the hood. This is very important.\nCombined with a very simple way of making Nim primitives we can quickly cobble up a 6 line primitive word called sum that will sum up the ints in a block. We simply use the fact that we know the block consists only of integers. I am guessing the sum function of Python does something similar.\nHere is the code heavily commented:\n# nimPrim is a Nim macro to make Spry primitives # First argument is the word to bind, second is if # this is an infix word (first argument on the left) # and finally how many arguments the primitive expects. nimPrim(\u0026#34;sum\u0026#34;, true, 1): # The local variable spry refers to the Interpreter # evalArgInfix(spry) is a function call that returns # the infix argument evaluated at the call site. # We then cast this to a SeqComposite which is the # abstract super type of Blocks. let blk = SeqComposite(evalArgInfix(spry)) var sum = 0 # This is Nim iteration over the nodes member # of the SeqComposite, a seq of Nodes. for each in blk.nodes: # We cast the node to IntVal since we know # it\u0026#39;s an int, and then we can get the value member # which is a regular Nim int. sum = sum + IntVal(each).value # All Spry functions returns Nodes so we wrap the int # as a Node using newValue() which will wrap it as an # IntVal. return newValue(sum) It\u0026rsquo;s worth noting that almost all primitive words in Spry are written using this same pattern - so there are lots of examples to look at! Of course this is a bit of \u0026ldquo;cheating\u0026rdquo; but it\u0026rsquo;s also interesting to see how easy it is for us to drop down to Nim in Spry. We create a new word bound to a primitive function in exactly 6 lines of code.\nSo how fast is Spry using this primitive word? It sums up in blazing 0.15 seconds, about 100x faster than Cog and 10x faster than NodeJS for summing up. And yeah, even 2x faster than Python!\nAnd yes, we can easily make this primitive smarter to handle blocks with a mix of ints and floats and a proper exception if there is something else in there - then it ends up being 17 lines of code, and still almost as fast, 0.17-0.18 seconds! I love you Nim.\nIn summary, Cog - which is what I am most interested in comparing with - is fast but my personal goal is to get Spry within 5x slower in general speed - and that will be a good number for a pure interpreter vs an advanced JIT. And if we throw in primitive words - which is not hard - Spry can be very fast!\n"},{"title":"Spry vs Allen","permalink":"https://goran.krampe.se/2016/05/14/spry-vs-allen/","summary":"\u003cp\u003eAllen Wirfs-Brock \u003ca href=\"http://www.wirfs-brock.com/allen/posts/754\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ewrote down a bullet list\u003c/a\u003e\n of what he thought actually made it possible for the Alan Kay team to \u003ca href=\"http://worrydream.com/EarlyHistoryOfSmalltalk/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ecreate Smalltalk\u003c/a\u003e\n, and many other ground breaking things, at Xerox PARC in the 70s. Let\u0026rsquo;s take a look at \u003cstrong\u003ehis bullets one by one\u003c/strong\u003e and see how it applies to Spry and my puny little effort around it :)\u003c/p\u003e\n\u003cimg src=\"/spry/assume.jpg\" alt=\"Assume\" style=\"display:block; margin:0 auto;\"\u003e","content":"Allen Wirfs-Brock wrote down a bullet list of what he thought actually made it possible for the Alan Kay team to create Smalltalk , and many other ground breaking things, at Xerox PARC in the 70s. Let\u0026rsquo;s take a look at his bullets one by one and see how it applies to Spry and my puny little effort around it :)\nLook 20 years into the future Link to heading That\u0026rsquo;s obviously hard to do, but I am trying a little bit by questioning every little thing that many consider not being even relevant or possible to question. Some examples are:\nWhy we can\u0026rsquo;t do OO in some new novel ways Why we are so stuck in having source code in files Why we still only share code instead of sharing live objects Why our IDEs still can\u0026rsquo;t do things like backwards debugging or modifying code while running Everyone is so busy \u0026ldquo;doing stuff\u0026rdquo; that noone takes the time to actually reflect. Can we really not create a development system in which I can see exactly what is going on? Is there really no more powerful ways to do debugging?\nSo I may not look into the future, but most good ideas come from someone doing something unexpected, weird, impossible or downright stupid. In Spry I want us to try a few of those :)\nExtrapolate technologies Link to heading I don\u0026rsquo;t really dare, but I think it\u0026rsquo;s safe to say that Virtual Reality is probably going to be accessible everywhere. JavaScript has hopefully waned but leaving behind a new much lower threshold to programming being the norm, not the exception. Everyone wants to be able to program. Hardware is basically free, very capable and everywhere. People tend to think that the web is taking over everything, but I don\u0026rsquo;t think its that simple - I think diversity is going to be much higher due to new companies creating new kinds of devices. Many more devices.\nHow does this affect choices in Spry? Well, I tend to not let performance considerations hinder various ideas. I also focus pretty hard on mobility of code and data, since I think we should be able to find a lot more models of computing in the area of distributed systems.\nFinally I do think DSLs in different shapes or forms will play a big part in the future - so Spry should have excellent capabilities for that.\nI also want Spry to be modular on most levels, while still being fairly simple.\nFocus on people Link to heading The Smalltalk team was focused on user interfaces, education and children. With Spry \u0026ldquo;people\u0026rdquo; means primarily \u0026ldquo;developers\u0026rdquo;.\nI don\u0026rsquo;t think 20 years will remove the need for writing code, but the pressure for fast results will be immensely higher. I also think the boundaries of computing will be much fuzzier and that we will need to have more advanced tools to create and mold code into doing what we want. Things will run on many devices, distributed in novel ways reaching places in our lives we can not really imagine.\nI want to create and modify systems live as they run, as they are being used. Not just run locally, or as prototypes, but as they run live in deployment. Continuous deployment will probably evolve into 100% live online development. How will that affect developers? What tools do we need? How can we evolve a live system with confidence?\nThis implies we will have to create much more powerful ways to create, debug and modify code. We need to raise the abstraction levels, but perhaps a key to that is to create a homoiconic language that lends itself to introspection and self reference. Smalltalk didn\u0026rsquo;t do that (only to some extent), nor did JavaScript. The Lisp family of languages did to some extent, but for various reasons never really took off. Hard to say why.\nCreate a vision Link to heading One vision is a globally shared live system of cooperating Spry objects. Like GemStone/S but on a global scale, and taken even further to the extreme. Today developers share code - dead code - via various package catalogs and copy/paste forums. The SaaS and PaaS etc are trying to create shared platforms, but it\u0026rsquo;s still very much centered around the same coding model where we don\u0026rsquo;t share actual functionality, but merely code and libraries to recreate the functionality on our own.\nTo be concrete - instead of downloading a library and create a small service that consumes a live feed of data and produces a stream of Spry objects, in Spry we would find not a library, but a live running existing service that we just hook into. The module is not dead code, but actually a live and running service.\nThis is homoiconicity driven all the way! During the years sharing of objects have been tried via various RPC-ish standards like CORBA or RMI, but those standards have always revolved around static early binding and separate specifications and have thus later been completely run over by late binding self describing technologies like REST-ful APIs using JSON and similar \u0026ldquo;soft\u0026rdquo; formats. Late binding and self description is key for how modern development is done to a large extent - experimentation.\nAnother vision is Spry being a language to serve as a new foundation for transferable portable active code. Kinda like a JavaScript that doesn\u0026rsquo;t suck and that is homoiconic and thus easy to make tools for.\nBut in the end\u0026hellip; I don\u0026rsquo;t have any grand delusions about Spry - its all for fun and I just hope some of us will find it useful!\nA Team of Dreamers and Doers Link to heading Obviously I don\u0026rsquo;t have this. Yet. I hope that if I can make enough progress on my own - then people will join. And I stand on firm shoulders in the form of Nim which makes Spry suffering less of NiH (no pun intended). I hope that some Smalltalkers will eventually join, but I need a good solid language manual and perhaps even a reasonably interesting IDE to get any real traction.\nPrototype the Vision Link to heading Spry has almost reached the point where we can start working on the fun stuff. The module system, serialization mechanisms and lossless AST improvements are all crucial steps towards this. Next step is getting the OO model working and do the Sophia integration to get a working image based system. After that I suspect its time to make a first IDE. I do have some plans and ideas for that too :)\nLive Within the Prototype Link to heading I think this is definitely important. The existing REPL is just a crude first trivial step. But it will get better!\nMake It Useful to You Link to heading I personally want to apply Spry in the domains of VR and IoT. Web systems is no longer that interesting to me, but if someone would like to evolve Spry compiled to js - I would be very grateful.\nAmaze the World Link to heading Hopefully, eventually! :)\n"},{"title":"Spry Modules, part II","permalink":"https://goran.krampe.se/2016/05/03/spry-modules-ii/","summary":"\u003cp\u003eIn the \u003ca href=\"http://goran.krampe.se/2016/04/16/spry-modules\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003elast article\u003c/a\u003e\n I outlined a simple \u003cstrong\u003emodel of modules\u003c/strong\u003e and that is kinda implemented but needs a few fixes. The next step is how to find and combine modules and this is an area where I want to push the envelope a bit. Most popular package/module systems today are quite trivial in nature. Often it\u0026rsquo;s a command line tool that queries central catalog(s) and then proceeds by downloading code in the form of source files onto disk. Then the compiler or runtime environment finds and loads the code by simply looking for files on disk. There are several parts of this that are very primitive.\u003c/p\u003e\n\u003cp\u003eWhen I built \u003ca href=\"http://map.squeak.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSqueakMap\u003c/a\u003e\n waaay back I was already then tainted with the idea of \u003ca href=\"https://gemtalksystems.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eshared object models\u003c/a\u003e\n and one of the primary ideas in SqueakMap was to make sure each local Smalltalk environment got a full live object model of the catalog which then could be queried, viewed and reasoned about inside the Smalltalk environment. Much more powerful than a bunch of JSON files on disk. This led to the approach of downloading the full catalog in a serialized form - and then loading it into \u003ca href=\"http://www.squeak.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSqueak\u003c/a\u003e\n.\u003c/p\u003e\n\u003cp\u003eWith \u003ca href=\"http://sprylang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSpry\u003c/a\u003e\n I want us to create a simpler meta model - at least for starters - but with an even smarter infrastructure backing it\u0026hellip;\u003c/p\u003e","content":"In the last article I outlined a simple model of modules and that is kinda implemented but needs a few fixes. The next step is how to find and combine modules and this is an area where I want to push the envelope a bit. Most popular package/module systems today are quite trivial in nature. Often it\u0026rsquo;s a command line tool that queries central catalog(s) and then proceeds by downloading code in the form of source files onto disk. Then the compiler or runtime environment finds and loads the code by simply looking for files on disk. There are several parts of this that are very primitive.\nWhen I built SqueakMap waaay back I was already then tainted with the idea of shared object models and one of the primary ideas in SqueakMap was to make sure each local Smalltalk environment got a full live object model of the catalog which then could be queried, viewed and reasoned about inside the Smalltalk environment. Much more powerful than a bunch of JSON files on disk. This led to the approach of downloading the full catalog in a serialized form - and then loading it into Squeak .\nWith Spry I want us to create a simpler meta model - at least for starters - but with an even smarter infrastructure backing it\u0026hellip;\nWhat we have Link to heading A quick summary of where the Spry modules implementation is today:\nA Module is just a Spry Map - a key value structure obviously forming a namespace. Since a Module is a Map and Spry is homoiconic, it can hold anything, not only code but any kind of Spry node. When loaded into memory a Module is held in a global name. We don\u0026rsquo;t allow nested Modules in a hierarchy, I think it invites convoluted solutions and doesn\u0026rsquo;t fit the \u0026ldquo;catalog\u0026rdquo; model either which typically is flat. The Module has meta information kept inside in yet another Map under the key meta with members like name and version. First I was thinking of using _meta but I am opting instead for plain meta. Collisions? Deal with it. Nodes in the Module can be referenced from the outside using module qualified eval- or get words like Foo::bar or ^Foo::bar. There is no import mechanism but there is a global word modules referencing the Modules that should be consulted in order for lookups of non qualified words. Modules can be trivially serialized or deserialized in source form, just like any other Spry node. This is how we serialize any node in Spry, remember that data and code is the same thing, its all turtles\u0026hellip; I mean nodes. Thus, the source code, or file format, of a Map (and thus also a Module) looks like this:\n# A Map is just a bunch of assignments inside a Curly. A Curly in Spry is just a sequence of Nodes. # After parsing we have a Curly which is still just \u0026#34;data\u0026#34;. If we evaluate the Curly Spry will # execute the code inside it and at the end return the Map of locals that was populated by the code. { # First is a very minimal meta Map holding the name of the Module in # the form of a literal Word which is similar to a Symbol in Ruby/Smalltalk. # There is no mandatory information, nor is the meta Map itself mandatory. meta = { name = \u0026#39;Foo } # This just assigns 13 to x in the local scope Map foo = 13 # Same again, but we can of course have funcs or whatever in a Module adder = func [:x + :y] } If we store this as Foo.sy (.sy being the Spry file extension I use) we can trivially load it into Spry with loadFile: \u0026quot;Foo.sy\u0026quot;. This is an example of a prefix keyword func, it could just as well have been named loadFile, but I am experimenting with finding good Spry conventions around this, but that\u0026rsquo;s the subject of another article :)\nIssues so far Link to heading I have realized two isses so far:\nFoo::bar as implemented at the moment looks directly in globals for Foo. The current \u0026ldquo;module is a Map\u0026rdquo; doesn\u0026rsquo;t create a closure for the module itself where it could keep private code or state. The first issue, on my fourth thought, I decided it\u0026rsquo;s powerful to have Foo::bar be implemented as equivalent to Foo at: 'bar. So I will make sure to look for Foo first using normal scoping lookup. This enables shadowing of modules but it should be a Big No No because it turns into a kind of import statement and as a reader of code you wouldn\u0026rsquo;t be sure what Foo::bar really resolves to. But Spry can easily detect if you introduce a Module shadow, and hit you hard on the head!\nThe second issue is more intricate and caused me to think quite hard on which route to take. If we wrap the Map inside a block, we get a closure, and then we could create private bindings in that closure. That resembles the techniques used in the JavaScript community, so definitely not an odd concept. But it also leads to the module not being serializable as itself. The Map is no longer the module itself, instead it only holds the \u0026ldquo;exports\u0026rdquo; of the Module.\nI want to stick to a declarative Map style and introduce hooks like Foo::init that is called upon Module load and Foo::release perhaps on Module unload. But how should private state of the module be created? Let that simmer while we dive into another aspect\u0026hellip;\nSource code formatting Link to heading It would be pretty nice if we could unify storage of Modules (Spry nodes in general) so that we could simply store: Foo asFile: \u0026quot;Foo.sy\u0026quot;. Today we can do that, but all indentation and comments are lost in the round trip! So\u0026hellip; it would be super slick if we could once and for all get rid of source code :). Smalltalk never went all the way on this - although Smalltalk came quite close. Various ideas around this:\nIntroduce a pretty printer and simply force us to use it always making formatting \u0026ldquo;moot\u0026rdquo;, but comments are still not handled. Somehow collect comments and formatting and keep it on the side associated with the AST. Extend the AST to also include comments and formatting somehow, so that they are not lost but kept in the AST. I am leaning towards the latter, even though it\u0026rsquo;s obviously insane.\nSo\u0026hellip; if I extend Node with an optional string containing the \u0026ldquo;all whitespace and comments\u0026rdquo; right before the Node itself - then we should be able to serialize/deserialize without losses, except for anything coming after the very last node :). Default whitespace is a single space, we represent that as nil. And sure, wasting a full reference in every Node? I agree, completely nuts, but perhaps we can somehow magically avoid that later on. It still is too tempting to try!\nProposal Link to heading Fiddling with closures for modules, as is done in JavaScript, feels hacky. First of all, I don\u0026rsquo;t like modules that are primarily constructed by running code. It\u0026rsquo;s too brittle. I want to have a loading phase that is declarative-ish, and then an activation phase where the module can execute code in specific hooks. This means that Spry can analyze the module when its loaded to check for collisions or other things. The simplest way of loading modules is to simply eval the Curly, to get a Map - but we could trivially create a \u0026ldquo;safe Module loader\u0026rdquo; that doesn\u0026rsquo;t use plain eval and thus we would plug that security hole. For now, eval is fine though!\nThis leaves us with the question on how to create private state in the Module.\nIn earlier articles I introduced the concept of scoped words, .x and ..x, but haven\u0026rsquo;t followed through on actually implementing them. The .x could mean \u0026ldquo;start resolving in closest enclosing Module or Object\u0026rdquo;. This would make it work like instance variable access - and a Module will most obviously turn into an Object when I get the OOP stuff in place. Now, to make x be private I am thinking of _x. I stared at the ASCII table and didn\u0026rsquo;t think the alternatives were good. And most developers use _ to denote privateness. This means I have decided to go with:\n.x means in the closest enclosing Object. To begin with the closest enclosing Map is good enough. ..x means somewhere outside of the closest enclosing Map. The definition if that we can experiment with later. _x means just like .x but private Next step Link to heading Fix Foo::bar to resolve Foo normally first. This enables :: to be used for \u0026ldquo;property access\u0026rdquo; in general. Implement .x and _x to behave as described above. Implement comments and formatting collection in the Node. Make some module testing this out. Happy Sprying!\n"},{"title":"Spry Modules","permalink":"https://goran.krampe.se/2016/04/16/spry-modules/","summary":"\u003cp\u003eAs discussed in \u003ca href=\"http://goran.krampe.se/2016/04/09/spry-image-model/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ethe previous article\u003c/a\u003e\n I want Spry to have a trivially accessible persistence mechanism enabling something similar to the \u003cstrong\u003eSmalltalk image model\u003c/strong\u003e, but based on a database. The memory organisation in Spry is basically nested Maps. After dwelling a bit on the inevitable hard question about \u003cstrong\u003emodules and namespaces\u003c/strong\u003e I have decided on a design that I hope will turn out simple and reasonably powerful!\u003c/p\u003e\n\u003cimg src=\"/spry/modules.jpg\" alt=\"Modules\" style=\"float:right; margin:0 0 1em 1em;\"\u003e\n\n\u003cp\u003eSmalltalk has a Dictionary holding all the globals forming \u0026ldquo;the roots\u0026rdquo; of the object memory. In Smalltalk this Dictionary is also itself a global variable accessible as \u003ccode\u003eSmalltalk\u003c/code\u003e, in other words \u003ccode\u003eSmalltalk == (Smalltalk at: #Smalltalk)\u003c/code\u003e. The primary use of \u003ccode\u003eSmalltalk\u003c/code\u003e is to hold all classes by name, so they are all reachable as globals. Obviously \u003ccode\u003eSmalltalk\u003c/code\u003e can also hold any kind of object (not just classes) as a global.\u003c/p\u003e\n\u003cp\u003eSpry also has such a top level Dictionary, but in Spry we call a Dictionary a \u003ccode\u003eMap\u003c/code\u003e to be a little bit more aligned in terminology with other languages (and it\u0026rsquo;s shorter). This top level Map is the \u003ccode\u003eroot\u003c/code\u003e Map and it is accessible via the word \u003ccode\u003eroot\u003c/code\u003e. In Spry the \u003ccode\u003eroot\u003c/code\u003e word is actually bound to a primitive function returning this \u003ccode\u003eMap\u003c/code\u003e, so in Spry we also have \u003ccode\u003eroot == (root at: 'root)\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eOk, so Spry has a \u003ccode\u003eMap\u003c/code\u003e of globals and one way of using Spry is simply by populating \u003ccode\u003eroot\u003c/code\u003e with words bound to functions making these functions globally accessible, it\u0026rsquo;s how I have done it so far. Yeah, yeah, I know, but for smaller systems it probably works just fine!\u003c/p\u003e\n\u003cp\u003eBut\u0026hellip;\u003c/p\u003e","content":"As discussed in the previous article I want Spry to have a trivially accessible persistence mechanism enabling something similar to the Smalltalk image model, but based on a database. The memory organisation in Spry is basically nested Maps. After dwelling a bit on the inevitable hard question about modules and namespaces I have decided on a design that I hope will turn out simple and reasonably powerful!\nSmalltalk has a Dictionary holding all the globals forming \u0026ldquo;the roots\u0026rdquo; of the object memory. In Smalltalk this Dictionary is also itself a global variable accessible as Smalltalk, in other words Smalltalk == (Smalltalk at: #Smalltalk). The primary use of Smalltalk is to hold all classes by name, so they are all reachable as globals. Obviously Smalltalk can also hold any kind of object (not just classes) as a global.\nSpry also has such a top level Dictionary, but in Spry we call a Dictionary a Map to be a little bit more aligned in terminology with other languages (and it\u0026rsquo;s shorter). This top level Map is the root Map and it is accessible via the word root. In Spry the root word is actually bound to a primitive function returning this Map, so in Spry we also have root == (root at: 'root).\nOk, so Spry has a Map of globals and one way of using Spry is simply by populating root with words bound to functions making these functions globally accessible, it\u0026rsquo;s how I have done it so far. Yeah, yeah, I know, but for smaller systems it probably works just fine!\nBut\u0026hellip;\nModules Link to heading But we do want a Module concept and given that I once designed a Namespace model for Squeak (that never was accepted) - it was inevitable I guess that it would reappear in Spry! :)\nAs many other languages do, I also simplify by making a \u0026ldquo;Module\u0026rdquo; do double duty as a \u0026ldquo;Namespace\u0026rdquo;. It\u0026rsquo;s a reasonable approximation although to be precise a Module is normally a deployment, versioning and distribution unit and a Namespace should ideally be aligned with how we humans are organised, but\u0026hellip; whatever. In Spry I also simplify by not allowing nesting of Modules. A Module is simply a Map bound to a global word.\nModules need to have meta information about them. In Nim we use a Foo.nimble file to contain this meta information. In the JavaScript world there is a package.json file containing meta information. In Spry, since a Module is a Map, we let the _meta key hold a Map of meta information:\n_meta = { name = \u0026#34;Foo\u0026#34; version = \u0026#34;1.0\u0026#34; author = \u0026#34;Göran Krampe\u0026#34; } The name of the Module is thus only kept as meta information, this means that the code loading the module into our system decides what the Module should actually be named - thus we can choose to load a Module Foo by the name Foo2 if we already have a Module called Foo in the system. It could for example be used to have two different versions of the same Module loaded at the same time.\nSo how do we refer to things in different Modules? Obviously we can do it manually using (root at: 'Network) at: 'Socket, it\u0026rsquo;s just a global Map after all, but Network at: 'Socket is simpler. I am also introducing yet another word type - a Module qualified word. It would look like Network::Socket and be evaluated as Network at: 'Socket. If we load another Foo as Foo2, then all existing references like Foo::Cat will of course not refer to the new Foo2, but we could easily scan for them and modify them, if we so wish.\nTo import\u0026hellip; or not! Link to heading Finally, we face the issue of imports. Almost all programming languages use imports, often per class or file, but also per module. It\u0026rsquo;s worth recognizing what true purpose they actually serve.\nOne use of them is to avoid typing long names in the actual code, but \u0026hellip; that would typically only be an issue if module names where.. say very long like com.MyCoolCompany.ProjectX.Base.Common, but they aren\u0026rsquo;t in Spry, since we don\u0026rsquo;t allow nesting nor do we want people to use Internet domain names like that.\nIt can be used to constrain the allowed references a Module can have, but\u0026hellip; in my experience it\u0026rsquo;s not often used to do that. One could however imagine a system of declarative rules of what modules can access what other module, or which group of modules can depend on which other group. In fact, I designed such a tool for Java back in \u0026hellip; waaay back.\nTo enhance completion, only completing within the imported union of modules. I don\u0026rsquo;t really view this as a critical thing, and it can also be solved using heuristics. Smalltalk systems also complete these days, and not having imports hasn\u0026rsquo;t really made it less useful.\nTo act as documentation for a Module showing what other Modules it uses, but\u0026hellip; then we should not allow fully qualified references in the code since that invalidates this purpose. And we could trivially scan and find all usages within the Module without the import statements.\nTo sum it up\u0026hellip; Link to heading In my proposal for Squeak there were no imports either, the idea was to always have the full reference in the source code, but to let browsers \u0026ldquo;render them short\u0026rdquo; if the unqualified name still was unique in the image. In Spry I am opting for a slightly different approach:\nFor a regular word lookup eventually ends up looking in root for globals. If it fails, it looks through the Modules one by one until it finds a hit. This means Socket will resolve to Network::Socket if Network is the first module found containing that word, and there is no global Socket shadowing it. For a module qualified word, like Network::Socket, lookup is directly in the module by that name, we never look at globals. If there is no hit, it\u0026rsquo;s not resolved, so no need to look elsewhere. This means we can still use Socket in short form, but be aware that it means \u0026ldquo;Give me the first thing you find called Socket\u0026rdquo;. If we qualify it means \u0026ldquo;Give me Socket in the Network module\u0026rdquo;.\nThus, if we let root at: 'modules be a Block of the modules that wish to participate in such an ordered lookup - that should be enough!\nNext Steps Link to heading So I will:\nWrite some module tests. Add the global modules block and adjust lookup to use it for non qualified words. Add the module qualified word and it\u0026rsquo;s special lookup. Make some base modules and add some mechanisms to ispry (the REPL) to use them. When this works it\u0026rsquo;s getting time to hook into Sophia !\nHappy Sprying!\n"},{"title":"Spry image model","permalink":"https://goran.krampe.se/2016/04/09/spry-image-model/","summary":"\u003cp\u003eIn developing Spry - \u003ca href=\"/ni-is-now-spry\" \u003erenamed from Ni\u003c/a\u003e\n - I am getting closer to the \u003cstrong\u003eReally Fun Stuff\u003c/strong\u003e.\u003c/p\u003e\n\u003cp\u003eAs a Smalltalker I dream \u0026ldquo;bigger\u0026rdquo; than just managing source code as text in files\u0026hellip;\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://www.azquotes.com/quote/847274\" title=\"Kent Beck quote\"\u003e\u003cimg src=\"http://www.azquotes.com/picture-quotes/quote-i-mean-source-code-in-files-how-quaint-how-seventies-kent-beck-84-72-74.jpg\" alt=\"I mean, source code in files; how quaint, how seventies! - Kent Beck\"  /\u003e\n\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eSmalltalk uses the \u0026ldquo;image model\u0026rdquo; in which the system is alive and running all the time, the full development environment is also live together with your application, and we are in fact modifying object structures when we develop Smalltalk programs. We can also snapshot that object memory onto disk and fire it up somewhere else. Several Lisp implementations have used a similar approach I think.\u003c/p\u003e\n\u003cp\u003eThe image model has tons of really cool benefits, I don\u0026rsquo;t have time repeating all of them, but a modern implementation of the idea should take a few things into account that was not considered in the 1970s:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eThe \u0026ldquo;image\u0026rdquo; in Spry will be buildable from source\u003c/li\u003e\n\u003cli\u003eYou should be able to use Spry without the image mechanism (you can already)\u003c/li\u003e\n\u003cli\u003eSpry code will have a readable text format and file structure\u003c/li\u003e\n\u003cli\u003eThe image model does not have to be all or nothing, it can be partial\u003c/li\u003e\n\u003cli\u003eThe image mechanism will be a module for the Spry VM, so you can skip it entirely\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eSome argue that the image model has downsides - like being an \u0026ldquo;ivory tower\u0026rdquo; incapable of interacting with the outside world. The Smalltalk environments have indeed historically suffered a bit in varying degree, but we can easily find ways around those issues while still \u003cstrong\u003ereaping the awesomeness of a fully live\u003c/strong\u003e programming environment, especially if we give the above items proper thought \u003cstrong\u003efrom the start\u003c/strong\u003e.\u003c/p\u003e\n\u003cp\u003eWith Spry I think I have a beginning to a novel approach\u0026hellip; as well as taking the above into account.\u003c/p\u003e","content":"In developing Spry - renamed from Ni - I am getting closer to the Really Fun Stuff.\nAs a Smalltalker I dream \u0026ldquo;bigger\u0026rdquo; than just managing source code as text in files\u0026hellip;\nSmalltalk uses the \u0026ldquo;image model\u0026rdquo; in which the system is alive and running all the time, the full development environment is also live together with your application, and we are in fact modifying object structures when we develop Smalltalk programs. We can also snapshot that object memory onto disk and fire it up somewhere else. Several Lisp implementations have used a similar approach I think.\nThe image model has tons of really cool benefits, I don\u0026rsquo;t have time repeating all of them, but a modern implementation of the idea should take a few things into account that was not considered in the 1970s:\nThe \u0026ldquo;image\u0026rdquo; in Spry will be buildable from source You should be able to use Spry without the image mechanism (you can already) Spry code will have a readable text format and file structure The image model does not have to be all or nothing, it can be partial The image mechanism will be a module for the Spry VM, so you can skip it entirely Some argue that the image model has downsides - like being an \u0026ldquo;ivory tower\u0026rdquo; incapable of interacting with the outside world. The Smalltalk environments have indeed historically suffered a bit in varying degree, but we can easily find ways around those issues while still reaping the awesomeness of a fully live programming environment, especially if we give the above items proper thought from the start.\nWith Spry I think I have a beginning to a novel approach\u0026hellip; as well as taking the above into account.\nThe Smalltalk model Link to heading Most Smalltalks (not all) have been image based and the image has simply been a \u0026ldquo;memory snapshot\u0026rdquo; of the whole system down to a single disk file. Although quite novel both then and now - the concept of a single dump onto a file is rather primitive. Today we have TONS of different advanced database engines to choose from - why not use one of them instead?\nYes, GemStone is a remarkable exception to the traditional Smalltalk image model. Already in the late 1980s they realized that the object memory could be made transparently distributed, multiuser, transactional and persistent. GemStone is simply DARN cool and I haven\u0026rsquo;t seen anything even close in other languages. But it\u0026rsquo;s not open source, and it\u0026rsquo;s expensive. And\u0026hellip; can be a bit complex too.\nCan we do something similar to GemStone but much simpler? Let\u0026rsquo;s start in the single user perspective. Assume we have a transparently integrated advanced and super fast database engine. Sure, single user, but that will give us a strong platform to stand on for code management, IDE development and a lot more.\nStorage format Link to heading But hold on - first we need to decide on a suitable format to store in a database.\nI thought briefly about the binary path where we simply store pages of RAM onto disk in order to avoid serialization/deserialization - but I opted out. It\u0026rsquo;s complicated and it doesn\u0026rsquo;t fit well into the idea of having future multiple implementations of the Spray VM catering to different eco systems. I also think CPUs are insanely fast these days so serialization/deserialization is not a bottleneck.\nSo let\u0026rsquo;s presume we serialize, in what format? Definitely in a readable format I would say. What about JSON then? Mmm, JSON is simple and TONS of databases these days rely on it, and in fact Spry will have really nice abilities to manipulate and integrate JSON - but we have a more natural choice in Spry.\nSpry is homoiconic and has a simple and easily parsed free form syntax of its own. In the name of unifying concepts and simplicity - we obviously just use Spry! This would be slightly in analogy with the storeOn: and readFrom: mechanisms that Smalltalk had from the start storing data \u0026ldquo;as code\u0026rdquo;. But Spry is MUCH cleaner and consistent here, in the way Lisp is. The data model of Spry, including the model of executable code, is the AST tree and the syntax of Spry mirrors this tree.\nSerialization Link to heading After some optimizations in the current parser I made some tests on my laptop. I daftly generated some fake \u0026ldquo;data\u0026rdquo; in the Spry syntax and can happily note that Spry compiles (deserializes) about 10Mb source per second into AST nodes. And it seems to scale pretty fine too. The serialization step is even faster.\nCompression Link to heading To put some icing on that cake I threw in LZ4 compression which is wickedly fast, so fast it isn\u0026rsquo;t even noticed even when doing a full back to back cycle of a 430 Mb source file. And source is very amenable to compression, although my sample is repetitive so not a good reference.\nHere is a trivial Spry script that reads a compressed file, uncompresses it, compiles it (deserialize) and then serializes it again and compresses it before writing it back on disk:\n#!/usr/bin/env spry writeFile \u0026#34;full3-lz42.sy\u0026#34; compress serialize deserialize uncompress readFile \u0026#34;full3-lz4.sy\u0026#34; These commands I defined in prefix fashion which means the evaluation ends up as a chain from right to left. One could just as easily have defined them as infix to get a reverse evaluation, or one could use an Elixir style \u0026ldquo;pipe\u0026rdquo; function to get that effect. Spry is flexible here and obviously some kind of editor support or conventions may be needed to avoid confusion.\nSo where are we now? We can read and write files (trivial of course), compress/uncompress strings using liblz4 and serialize/deserialize strings into and from Spry AST nodes. This means we can now store and load code as well as data, and we could trivially extend the REPL with a regular \u0026ldquo;image model\u0026rdquo;.\nSophia Link to heading But let\u0026rsquo;s go all the way. Files are neat, but a really good database is better. I hunted high and low for something that seemed easy to use, with an interesting set of features and really, really good performance. I ended up choosing Sophia and I have a Nim wrapper of the C API of Sophia already cooking. I have a feeling this is going to be a blast, terabyte image size? No problem.\nWhen the wrapper is working it\u0026rsquo;s time to start thinking of how the memory model can be partitioned, manipulated through transaction boundaries, but that will be another article for another day!\nIf you want to chat about Spry, join up at http://gitter.im/gokr/spry ! Or at #spry on freenode.\n"},{"title":"Ni renamed to Spry!","permalink":"https://goran.krampe.se/2016/04/08/ni-is-now-spry/","summary":"\u003cp\u003eWhen I started out implementing my own language in Nim I named it \u0026ldquo;Ni\u0026rdquo; without that much thought actually. It was a pun on \u0026ldquo;smaller than Nim\u0026rdquo; (obviously one letter shorter!) and of course with a \u003ca href=\"https://en.wikipedia.org/wiki/Knights_who_say_Ni\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ereference to Monty Python\u003c/a\u003e\n.\u003c/p\u003e\n\u003cp\u003eBut\u0026hellip; really, \u003cstrong\u003ethe name \u0026ldquo;Ni\u0026rdquo; sucks\u003c/strong\u003e. It\u0026rsquo;s hard to say in general and since it\u0026rsquo;s often mentioned together with Nim the confusion is obvious. And it also turned out to be less than optimal to google for.\u003c/p\u003e","content":"When I started out implementing my own language in Nim I named it \u0026ldquo;Ni\u0026rdquo; without that much thought actually. It was a pun on \u0026ldquo;smaller than Nim\u0026rdquo; (obviously one letter shorter!) and of course with a reference to Monty Python .\nBut\u0026hellip; really, the name \u0026ldquo;Ni\u0026rdquo; sucks. It\u0026rsquo;s hard to say in general and since it\u0026rsquo;s often mentioned together with Nim the confusion is obvious. And it also turned out to be less than optimal to google for.\nSprylang.org Link to heading So from now on the language is called Spry and there are two domains registered for it pointing to the same place - sprylang.org and spry-lang.net . The main site is sprylang.org , I first registered the .net domain but later realized that sprylang is just as reasonable as spry-lang, and there the .org was not taken.\nWhy spry? Link to heading Well, to be honest I was just surfing for synonyms to various \u0026ldquo;nice words\u0026rdquo; and I stumbled over it. I was leaning towards \u0026ldquo;fleck\u0026rdquo; but a native english speaking friend talked me out of it. :) Spry jumped up from some thesarus site and\u0026hellip; it just feels nice. And the meaning of spry is also very fitting IMHO:\nSpry: full of life and energy — Merriam-Webster Dictionary\nOne of the primary goals of Spry is to be a fully 100% live programming language and environment.\nSpry: Moving or performing quickly, lightly, and easily — The American Heritage Roget’s Thesaurus\n\u0026hellip;and yeah, the agility and nimbleness is also a big part. Given the influence from \u0026ldquo;older\u0026rdquo; languages like Smalltalk, Rebol, Lisp and Forth - I can also see some sense in the typical use of the adjective spry - namely as pertaining to someone elderly! That\u0026rsquo;s fine with me.\nAnd hey, it\u0026rsquo;s triple creamed too\u0026hellip;\n"},{"title":"Nim meets Arduino","permalink":"https://goran.krampe.se/2016/02/25/nim-meets-arduino/","summary":"\u003cp\u003eI now work as the Team Lead at \u003ca href=\"http://evothings.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eEvothings\u003c/a\u003e\n and our \u003cstrong\u003eopen source\u003c/strong\u003e product is a Workbench for creating \u003cstrong\u003emobile HTML5 applications focused on IoT\u003c/strong\u003e, by editing and running them \u003cstrong\u003elive on the mobile device\u003c/strong\u003e inside our spiced up Cordova based \u0026ldquo;Evothings Viewer\u0026rdquo;.\u003c/p\u003e\n\u003cp\u003eI am of course partial here - but the tool is really easy to use, doesn\u0026rsquo;t force you into any specific framework or editor, enables a very quick development cycle and has tons of examples, tutorials, docs and some special IoT focused libraries like for example around BLE (Bluetooth Low Energy). You can have your code running on your phone literally within 1-2 minutes and you don\u0026rsquo;t need to install XCode or the Android tools, you can even run it just fine from your trusty Linux laptop! Just \u003ca href=\"http://evothings.com/download\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ego for it\u003c/a\u003e\n. Ok, enough of the sales talk\u0026hellip;\u003c/p\u003e\n\u003cp\u003eSince we are specializing in the IoT space we have our office filled to the brink with toys\u0026hellip; eh, I mean \u003cstrong\u003eIoT devices\u003c/strong\u003e of all kinds from all different vendors. Two IoT communication standards are particularly important in this space, and that\u0026rsquo;s \u003cstrong\u003eBLE and MQTT\u003c/strong\u003e. I have already written three \u003ca href=\"http://goran.krampe.se/2015/12/14/evothings-meets-phoenix/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eblog\u003c/a\u003e\n \u003ca href=\"https://evothings.com/evothings-does-mqtt-with-bluemix/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eposts\u003c/a\u003e\n \u003ca href=\"https://evothings.com/evothings-does-mqtt-with-vernemq-or-emqtt/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003earound\u003c/a\u003e\n MQTT using Evothings. Now I am instead focusing on BLE and particularly the \u003cstrong\u003eembedded device side of the story\u003c/strong\u003e.\u003c/p\u003e\n\u003cimg src=\"/evothings/mediatek-linkit-one.png\" alt=\"LinkIt-ONE\" style=\"float:left; margin:0 1em 1em 0;\"\u003e\n\n\u003cp\u003eThis led me to round up a bunch of devices at the office that are fairly technically capable and have BLE support. The one I selected was the \u003ca href=\"http://www.seeedstudio.com/wiki/LinkIt_ONE\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eLinkIt ONE development board\u003c/a\u003e\n from \u003ca href=\"http://labs.mediatek.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eMediaTek\u003c/a\u003e\n \u0026amp; \u003ca href=\"http://www.seeedstudio.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSeeed Studio\u003c/a\u003e\n. It\u0026rsquo;s an insanely feature packed little board (GSM/GPRS, GPS, Wifi, BLE, sound output, SD card) with decent computing power (ARM7 EJ-S, 16Mb flash, 4Mb RAM) while still remaining in the \u0026ldquo;medium\u0026rdquo; embedded space I would say, still ruling out plain Linux and regular tools. I consider the \u003ca href=\"https://www.raspberrypi.org\"\u003eRaspberri Pi\u003c/a\u003e or \u003ca href=\"http://getchip.com\"\u003eC.H.I.P\u003c/a\u003e and similar machines to be in the \u0026ldquo;large\u0026rdquo; embedded space, they are real computers and you can basically use whatever you like to develop on those.\u003c/p\u003e\n\u003cp\u003eThe medium and small devices can be programmed using for example \u003ca href=\"https://github.com/espruino\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eEspruino\u003c/a\u003e\n or \u003ca href=\"http://micropython.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eMicropython\u003c/a\u003e\n (two very interesting projects) but in many cases, for more demanding applications, \u003cstrong\u003eC/C++ is still king\u003c/strong\u003e simply because of size and performance advantages. And also the fact that hardware vendor SDKs are typically in C/C++. But \u003cstrong\u003ecould there be an alternative language out there?\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eA language that is just as fast and small that easily can use all these C/C++ SDKs?\u003c/li\u003e\n\u003cli\u003eA language with a syntax similar to Python made to be easy to write and read?\u003c/li\u003e\n\u003cli\u003eA language with soft realtime GC and a sane advanced type system with generics?\u003c/li\u003e\n\u003cli\u003eA language with a good standard library and friendlier than C++?\u003c/li\u003e\n\u003cli\u003eA language with compile time hygienic AST based macros written in the language itself?\u003c/li\u003e\n\u003cli\u003eA language offering an imperative style and not forcing OO if you don\u0026rsquo;t want to?\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eYep! Read on to find out\u0026hellip;\u003c/p\u003e","content":"I now work as the Team Lead at Evothings and our open source product is a Workbench for creating mobile HTML5 applications focused on IoT, by editing and running them live on the mobile device inside our spiced up Cordova based \u0026ldquo;Evothings Viewer\u0026rdquo;.\nI am of course partial here - but the tool is really easy to use, doesn\u0026rsquo;t force you into any specific framework or editor, enables a very quick development cycle and has tons of examples, tutorials, docs and some special IoT focused libraries like for example around BLE (Bluetooth Low Energy). You can have your code running on your phone literally within 1-2 minutes and you don\u0026rsquo;t need to install XCode or the Android tools, you can even run it just fine from your trusty Linux laptop! Just go for it . Ok, enough of the sales talk\u0026hellip;\nSince we are specializing in the IoT space we have our office filled to the brink with toys\u0026hellip; eh, I mean IoT devices of all kinds from all different vendors. Two IoT communication standards are particularly important in this space, and that\u0026rsquo;s BLE and MQTT. I have already written three blog posts around MQTT using Evothings. Now I am instead focusing on BLE and particularly the embedded device side of the story.\nThis led me to round up a bunch of devices at the office that are fairly technically capable and have BLE support. The one I selected was the LinkIt ONE development board from MediaTek \u0026amp; Seeed Studio . It\u0026rsquo;s an insanely feature packed little board (GSM/GPRS, GPS, Wifi, BLE, sound output, SD card) with decent computing power (ARM7 EJ-S, 16Mb flash, 4Mb RAM) while still remaining in the \u0026ldquo;medium\u0026rdquo; embedded space I would say, still ruling out plain Linux and regular tools. I consider the Raspberri Pi or C.H.I.P and similar machines to be in the \u0026ldquo;large\u0026rdquo; embedded space, they are real computers and you can basically use whatever you like to develop on those.\nThe medium and small devices can be programmed using for example Espruino or Micropython (two very interesting projects) but in many cases, for more demanding applications, C/C++ is still king simply because of size and performance advantages. And also the fact that hardware vendor SDKs are typically in C/C++. But could there be an alternative language out there?\nA language that is just as fast and small that easily can use all these C/C++ SDKs? A language with a syntax similar to Python made to be easy to write and read? A language with soft realtime GC and a sane advanced type system with generics? A language with a good standard library and friendlier than C++? A language with compile time hygienic AST based macros written in the language itself? A language offering an imperative style and not forcing OO if you don\u0026rsquo;t want to? Yep! Read on to find out\u0026hellip;\nNim Link to heading I have written extensively about Nim before, and there is even a blog article showing that Nim can even run on an Arduino UNO! To Nimmers this isn\u0026rsquo;t surprising, Nim compiles to performant C and if you turn off the GC etc, Nim can fit wherever C can fit.\nBut that article used the low level mechanics of interfacing with C/C++ and did not use c2nim , the excellent wrapper generation tool written in Nim by Andreas Rumpf, the primary author of Nim.\nWhat if we could use c2nim to wrap most of the Arduino and MediaTek C/C++ libraries used to access all the features of the LinkIt ONE?\nArdunimo Link to heading Two weeks ago I pushed Ardunimo to github. Cheesy name, but I couldn\u0026rsquo;t resist. Beware though, probably only me who have tried running this since you would need a LinkIt ONE!\nThe README at github shows how to get going and all this is ONLY tested on 64 bit Ubuntu 14.04. But the top dir contains a VagrantFile that I also threw together that will fire up a Ubuntu 14.04 and install and build all the Nim parts (Nim, nimble, c2nim) you need.\nThe fun part is that you don\u0026rsquo;t need anything else! The LinkIt ONE officially only supports development from Windows or OSX using the Arduino IDE, but I found some instructables showing that you can indeed use the Arduino IDE on Linux too. I used that and looking at what the Arduino IDE does, to craft the Makefile to gain full control over the build process and get rid of the Arduino IDE.\nSo if you are like me, comfy from the command line, this setup should be perfect!\nThe wrapper Link to heading Ardunimo consists of two Makefiles, one to create the wrapper and one to build the binary for the LinkIt ONE. A Nim wrapper consists of Nim modules, basically one .nim file for each header file of the C/C++ API we are wrapping. The top level Makefile will call the Makefile in the wrapper directory if needed, to generate the wrapper modules, but we can also do it manually in the wrapper directory using say make clean \u0026amp;\u0026amp; make. Then we get all the nim wrapper modules recreated:\ngokr@yoda:~/ardunimo/wrapper$ ls *.nim arduino.nim lgps.nim ringbuffer.nim vmdcl.nim vmuimisc.nim wiring_shift.nim ardunimo.nim lstorage.nim stream.nim vmota.nim winterrupts.nim wstring.nim binary.nim ltask.nim uartclass.nim vmpromng.nim wiring_analog.nim hardwareserial.nim message.nim variant.nim vmpwr.nim wiring_constants.nim itoa.nim panicoverride.nim vmappmgr.nim vmsys.nim wiring_digital.nim lflash.nim print.nim vmdatetime.nim vmthread.nim wiring.nim gokr@yoda:~/ardunimo/wrapper$ The Makefile uses the c2nim tool to generate these wrappers by parsing the header files from the SDK. These headers are in the src directory, and there are some local small modifications to them. Some details were harder to fix in the header files, so those files I ended up hand editing after the c2nim generation, and placing them into the fixed directory, so they are just copied from there. A bit more work to maintain of course.\nThe c2nim tool can generate wrappers following Nim naming conventions (CamelCase etc) but it caused some issues for me so I skipped that part.\nThe Makefile Link to heading The top level Makefile builds our binary that we can copy onto the LinkIt ONE. It does this by first compiling the Nim source code, for example blink.nim, into .cpp source code, which then is compiled using the same commands that the Arduino IDE uses to compile. Normally the Nim compiler calls GCC (or whichever C compiler) by itself, but here I perform the C++ compilation and linking as usual in the Makefile in order to gain a bit easier control over the compilation and link commands.\nBtw, this Makefile will also download the SDK and the ARM GCC to local directories, if they are missing.\nThe Arduino style is to have an include at the top, and then to define the setup() and the loop() functions that the Arduino framework then will call. This is how blink.nim looks like:\n# In nim we normally use import but wrapper/ardunimo.nim # needs to be included via include at the top. include ardunimo # ardunimo.nim defines two trivial templates, setup and loop # making it clean and convenient. This is not the normal # function syntax in Nim. setup: # Nim is indentation based just like Python pinMode(13, OUTPUT) loop: digitalWrite(13, LOW) delay(300) digitalWrite(13, HIGH) delay(300) Before you build and run the above - you need to patch Nim. Then you can continue to build and run, see instructions in README.\nIf we take a closer look at the ardunimo.nim file from the wrapper, it looks like this:\n# Some reasonable set of imports for a sketch import arduino, wiring, wiring_digital, wiring_constants # I couldn\u0026#39;t figure out how to get this include into the # sketch, it is needed in order to get setup/loop resolved # from Arduino\u0026#39;s main.cpp. {.emit: \u0026#34;\u0026#34;\u0026#34; #include \u0026#34;Arduino.h\u0026#34; \u0026#34;\u0026#34;\u0026#34;.} proc NimMain() {.importc.} # Convenience templates, nifty template setup(code: untyped): untyped = proc setup*() {.exportc.} = NimMain() # Initialize Nim since Arduino will not do it code template loop(code: untyped): untyped = proc loop*() {.exportc.} = code The first thing this file does is to import a reasonable base set of wrapper modules. Nim can do deadcode elimination (see nim.cfg for the compiler directives) so there is no harm in importing stuff. We also use a hack, an emit, to make sure the Arduino.h file is included, I couldn\u0026rsquo;t figure out how to get it otherwise. We import the NimMain() C-function that Nim has generated so we can call it. This is for Nim\u0026rsquo;s runtime support to get a chance to initialize itself. The entry point of the binary is not controlled by Nim so we need to do this call manually. Then we define two convenience Nim templates for setup() and loop() so that it looks cleaner and to include the call to NimMain(). Nim templates are AST based macros and very powerful. Making your own Link to heading Just write your own blabla.nim and then build it using make clean \u0026amp;\u0026amp; make PROJECT=blabla, it should hopefully work, although remember that the wrapper is by no means complete nor at all tested. :)\nblink2.nim is similar to blink.nim but creates at compile time, a Nim sequence with different pauses in it. nimicro.nim is a first step at getting the Ni VM running, it fails still, but it can at least run the trivial program consisting of a single integer literal \u0026ldquo;1000\u0026rdquo; :)\nNext steps Link to heading For the moment this experiment is paused, I am now more focusing on ARM mbed OS based development, so I might end up redoing something similar, but with mbed OS instead of Arduino.\nAnyway, hope someone found this interesting and fun!\n"},{"title":"Evothings + Phoenix = Neato","permalink":"https://goran.krampe.se/2015/12/14/evothings-meets-phoenix/","summary":"\u003cimg src=\"/evothings/evothings.png\" alt=\"Evothings\" style=\"float:left; margin:0 1em 1em 0;\"\u003e\n\n\u003cp\u003eI have just started working at \u003ca href=\"https://evothings.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eEvothings\u003c/a\u003e\n!\u003c/p\u003e\n\u003cp\u003eIt\u0026rsquo;s a fun gang making slick development tools and libraries for building mobile IoT apps. Evothings is pushing the envelope on \u003cstrong\u003ereally easy mobile development\u003c/strong\u003e focused on all the \u003cstrong\u003enew nifty IoT-devices\u003c/strong\u003e flooding us over the next few years.\u003c/p\u003e\n\u003cimg src=\"/elixir/phoenix-small.png\" alt=\"Phoenix\" style=\"float:right; margin:0 0 1em 1em;\"\u003e\n\n\u003cp\u003eIn \u003ca href=\"http://goran.krampe.se/2015/10/27/elixir-booming/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003emy last article\u003c/a\u003e\n I predicted \u003ca href=\"http://www.elixir-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eElixir\u003c/a\u003e\n to become \u003cstrong\u003ebig\u003c/strong\u003e and now that I am learning the Evothings tools I wanted to make an Evothings example that uses \u003ca href=\"http://phoenixframework.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ePhoenix\u003c/a\u003e\n, the Elixir web server framework, as a backend, using its channels mechanism for websocket communication.\u003c/p\u003e\n\u003cp\u003eCoinciding with the release today of \u003ca href=\"https://evothings.com/announcing-evothings-2-0-beta-2-released/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eEvothings Studio 2.0 beta 2\u003c/a\u003e\n (yay!) I will show step-by-step how to:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eInstall Evothings Studio locally. It\u0026rsquo;s just unpacking a zip :)\u003c/li\u003e\n\u003cli\u003eMake sure we can run the \u0026ldquo;BLE Scan\u0026rdquo; example app and modify it.\u003c/li\u003e\n\u003cli\u003eGet a Phoenix server up on a Debian/Ubuntu server on the internet.\u003c/li\u003e\n\u003cli\u003eModify the app and server to use Phoenix channels for publish/subscribe of scan data.\u003c/li\u003e\n\u003cli\u003eVerify it all works!\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eSince not everyone has a Linux server up on the internet \u003cstrong\u003eyou can skip step 3 and just use my public server :)\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eLet\u0026rsquo;s go!\u003c/p\u003e","content":" I have just started working at Evothings !\nIt\u0026rsquo;s a fun gang making slick development tools and libraries for building mobile IoT apps. Evothings is pushing the envelope on really easy mobile development focused on all the new nifty IoT-devices flooding us over the next few years.\nIn my last article I predicted Elixir to become big and now that I am learning the Evothings tools I wanted to make an Evothings example that uses Phoenix , the Elixir web server framework, as a backend, using its channels mechanism for websocket communication.\nCoinciding with the release today of Evothings Studio 2.0 beta 2 (yay!) I will show step-by-step how to:\nInstall Evothings Studio locally. It\u0026rsquo;s just unpacking a zip :) Make sure we can run the \u0026ldquo;BLE Scan\u0026rdquo; example app and modify it. Get a Phoenix server up on a Debian/Ubuntu server on the internet. Modify the app and server to use Phoenix channels for publish/subscribe of scan data. Verify it all works! Since not everyone has a Linux server up on the internet you can skip step 3 and just use my public server :)\nLet\u0026rsquo;s go!\nThe app Link to heading So what does the app do? The original Evothings sample app (that we intend to modify) scans for BLE (Bluetooth Low Energy) devices nearby and shows a list of them with some information. It\u0026rsquo;s a very simple example of using your mobile to scan for devices like Estimotes , TI SensorTags or any other device using BLE which modern mobile devices support. It looks like this:\nThe twist we will add is to let the app send this information to a Phoenix server reachable on the internet, onto a pubsub channel, and then subscribe to that channel in order to populate the list on screen. This means all the participating mobile devices will show the union of all currently scanning mobiles.\nThe Tech Stack Link to heading The Evothings mobile app we are modifying is written in Javascript and runs inside the Evothings Viewer - a hybrid web view client that we will install via App Store or Google Play . The viewer is based on Cordova but enhanced in various ways with libraries specifically for IoT scenarios.\nThe communication between the app and Phoenix will go over Secure Websockets abstracted inside Phoenix Channels .\nPhoenix is a new very exciting framework for building highly scalable and very robust web applications. It\u0026rsquo;s written in Elixir which is a fairly new language standing on the shoulders of a giant - Erlang .\nElixir compiles to Erlang bytecode so an Elixir application, when deployed, is in effect an Erlang application. This article is not explaining why you should be excited about Elixir , Erlang and Phoenix (you should!) but instead shows how to use Phoenix channels together with Evothings.\nInstalling Evothings Link to heading Step 1 is to install the Evothings Studio on your developer machine. Don\u0026rsquo;t worry, it\u0026rsquo;s just a zipped folder that you remove later if you don\u0026rsquo;t get hooked :)\nJust go to evothings.com/download , download the correct zip file for your platform and unpack it somewhere. Then run EvothingsWorkbench in the unpacked directory.\nWhen the Workbench opens up you find instructions there on how to proceed under the heading \u0026ldquo;Getting Started\u0026rdquo;. Follow steps 1 and 2 and then continue reading here!\nNOTE: Yes, we will make proper installers for Windows etc soon.\nJust to make sure you have your mobile device connected, try clicking RUN on one of the example apps listed under the Examples tab in the Workbench. You should see it running in your viewer on the mobile device. Easy, right?\nAdapting BLE Scan Link to heading Time for Step 2, making our own variant of the \u0026ldquo;BLE Scan\u0026rdquo; example. We will copy and modify it:\nFind the app \u0026ldquo;BLE Scan\u0026rdquo; in the list under the Examples tab, press the COPY button on it. In the dialog that pops up, change \u0026ldquo;Destination folder name\u0026rdquo; to \u0026ldquo;ble-multiscan\u0026rdquo;. This will copy the whole directory for the \u0026ldquo;BLE Scan\u0026rdquo; app into your own personal \u0026ldquo;My Apps\u0026rdquo; directory as the dialog shows. In the My Apps tab you now see your own \u0026ldquo;BLE Scan\u0026rdquo; (note the directory path saying ble-multiscan). Press RUN to see it running on your phone. Let\u0026rsquo;s change the name and title of the application. Press the CODE button and find the index.html file. Open it in any editor and change the title of the app on line 10 and line 53 to \u0026ldquo;BLE Multiscan\u0026rdquo;. Tada! Notice how it autoreloaded on your phone with the new name. The entry under My Apps should also have the new name. Feel free to press Start Scan on your mobile and see if you can find any BLE devices around, if not\u0026hellip; this whole exercise will get fairly boring :) Install Elixir and Phoenix Link to heading Ok, so we are up and running with Evothings. You have successfully modified and run your mobile app.\nNow let\u0026rsquo;s get a Phoenix server going\u0026hellip; There are multiple routes here you can take:\nUse your own Ubuntu box if you have one with a real ipname that you can make a free SSL cert for Get an AWS micro for free and use that one Bail out completely and just use my server on the net :) NOTE: You could in theory use your local dev machine but then you will also need to make sure your mobile device can reach your dev machine by ipname over wifi and you will also need to make a real cert for that ipname typically via StartSSL. This means it\u0026rsquo;s fairly impractical as you need a DNS name for your machine locally, and in addition you will need to get a proper cert for that specific name - which can also be done of course, but well, I don\u0026rsquo;t think many will try. :)\nI run Ubuntu or Debian if I can choose, and the following instructions are verified for Ubuntu 14.04.3. We are actually simply following instructions found in the Phoenix docs so if you need more details, take a look there.\nFirst we add the Erlang Solutions repo to get access to Erlang and Elixir, and then install the elixir package which sucks in Erlang too.\n$ wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb $ sudo dpkg -i erlang-solutions_1.0_all.deb $ sudo apt-get update $ sudo apt-get install elixir After that elixir --version should report something like Elixir 1.1.1.\nUsing mix, the Elixir build tool, we can now install the Elixir package manager hex which you can also browse online , just hit enter as confirmation.\n$ mix local.hex It will be installed as an archive (a zip file basically) locally in your current user\u0026rsquo;s home directory. Hex is like \u0026ldquo;npm\u0026rdquo; for Elixir. The mix tasks inside the archive are then available in mix, so running mix --help will now show a range of hex tasks available.\nWe then install Phoenix, the Elixir web framework. It is also packaged as an archive but there is no hardwired mix command like \u0026ldquo;local.phoenix\u0026rdquo; to install it, so we do it more explicitly using mix\u0026rsquo;s archive command.\n$ mix archive.install https://github.com/phoenixframework/phoenix/releases/download/v1.0.4/phoenix_new-1.0.4.ez After this we can list our installed archives and it should look like:\n$ mix archive * hex-0.9.0.ez * phoenix_new-1.0.4.ez Archives installed at: /home/gokr/.mix/archives We also notice that mix --help now shows the available task phoenix.new.\nFinally, we need nodejs and npm for various frontend tools that Phoenix uses like Brunch , and inotify-tools is for Phoenix live code reloading.\n$ sudo apt-get install nodejs-legacy npm inotify-tools Install PostgreSQL Link to heading In order to get a \u0026ldquo;full stack\u0026rdquo; Phoenix setup I also include information on how to get PostgreSQL going, although at the moment we don\u0026rsquo;t use PostgreSQL in this example.\nStart by installing it:\n$ sudo apt-get install postgresql And we also need to configure the password for the default user postgres that Phoenix likes to use by switching to the postgres user and run some pqsl:\n$ sudo su - postgres $ psql ALTER USER postgres PASSWORD \u0026#39;postgres\u0026#39;; \\q (enter) $ exit Phew! But now we should have all we need to build a Phoenix application.\nCreate the Phoenix application Link to heading I am doing this in my home directory, but feel free to do it wherever you like. Let\u0026rsquo;s use the mix tool to create a Phoenix application called \u0026ldquo;multiscan\u0026rdquo;, hit enter on dependency question:\n$ mix phoenix.new multiscan It should create a lot of stuff and end with something like:\nWe are all set! Run your Phoenix application: $ cd multiscan $ mix ecto.create $ mix phoenix.server You can also run your app inside IEx (Interactive Elixir) as: $ iex -S mix phoenix.server The concept with having a tool like mix using tasks to generate scaffolding is pretty neat to make sure all Phoenix apps follow the same structure, this is nothing new for Rails people of course but can be a new thing for some of us.\nOk, let\u0026rsquo;s do what we are being told. Ecto is the database abstraction in Phoenix (wrapping several different databases) so the ecto.create task will create a database:\n$ cd multiscan $ mix ecto.create This may prompt to install rebar, which is just fine. Then it should compile the whole application and end saying:\nGenerated multiscan app The database for Multiscan.Repo has been created. And hey, run some tests:\n$ mix test You should among other things see 4 tests, 0 failures in green.\nAnd we can also fire up our application which will start serve by default on port 4000:\n$ mix phoenix.server [info] Running Multiscan.Endpoint with Cowboy on http://localhost:4000 Cowboy by the way is the Erlang HTTP server that Phoenix uses. Apache\u0026hellip; Cowboy\u0026hellip; you get it.\nThen check all is working by surfing to http://localhost:4000 !\nIt should look like my server looks , only difference being my server runs HTTPS on port 1443.\nA single git repo Link to heading Note that you can ignore this section, but I just wanted to mention that you can easily have Evothings handle your app while it is contained in a subdirectory of the Phoenix server application.\nThe Evothings app is just a directory and Evothings Studio can keep track of several apps under My Apps regardless of where they are on your hard drive. This means we can easily maintain the whole system in a single git repository.\nIf you are making the Phoenix app on a server then this advice does not really apply. I did all my coding on my laptop and then cloned it over to my public server in the end.\nBut if you want to do this, let\u0026rsquo;s move the application into the Phoenix file tree under the name app:\n$ mv ble-multiscan ~/multiscan/app Then we update Evothings Studio\u0026rsquo;s notion of where the app is by removing it from My Apps by clicking the (x) - yeah, no worries. Then add it back to Evothings Studio by dragging the file ~/multiscan/app/index.html and dropping it on Evothings Studio. Evothings will pick up the directory path for index.html and will consider that directory to be the app.\nFinally, you can do the git dance inside ~multiscan:\n$ git init \u0026amp;\u0026amp; git add . \u0026amp;\u0026amp; git commit -m \u0026#34;Initial commit\u0026#34; Enable Phoenix Channels Link to heading Next we basically follow the guide on channels in the Phoenix documentation . First we enable a channel we call \u0026ldquo;scan\u0026rdquo; by adding the file web/channels/scan_channel.ex:\ndefmodule Multiscan.ScanChannel do use Phoenix.Channel # For now we just use a single public scan \u0026#34;room\u0026#34; def join(\u0026#34;scan:public\u0026#34;, _message, socket) do {:ok, socket} end # All other scan rooms are considered private def join(\u0026#34;scan:\u0026#34; \u0026lt;\u0026gt; _private_scan_id, _params, _socket) do {:error, %{reason: \u0026#34;unauthorized\u0026#34;}} end end Above we can see that we create our own module called ScanChannel and use the Phoenix.channel module inside it to gain access to those functions. Then we define two variants of our join function and we use pattern matching on the first argument to decide which one is used!\nThe first one basically says that the topic:subtopic \u0026ldquo;scan:public\u0026rdquo; is fine for anyone to join, we return the tuple {:ok, socket} signifying all was fine. :ok is the syntax for an Elixir atom which is basically the same as a symbol in Ruby or Smalltalk.\nThe second definition of join is nifty indeed. The underscores signify that we ignore those arguments, but the first parameter declaration is written as a concatenation of the string \u0026ldquo;scan:\u0026rdquo; with \u0026ldquo;something we ignore\u0026rdquo;.\nHehe, yeah, \u0026lt;\u0026gt; for string concatenation sure made my eyes widen too, and especially in the context of pattern matching, but dispatching on multiple functions like this is darn neat.\nThen we modify a single line in web/channels/user_socket.ex to add the above channel. Click \u0026ldquo;file\u0026rdquo; if you want the full raw file instead of the diff.\n@@ -2,7 +2,7 @@ defmodule Multiscan.UserSocket do use Phoenix.Socket ## Channels - # channel \u0026#34;rooms:*\u0026#34;, Multiscan.RoomChannel + channel \u0026#34;scan:*\u0026#34;, Multiscan.ScanChannel ## Transports transport :websocket, Phoenix.Transports.WebSocket For our mobile app the following is not really needed, but Phoenix also serves a web frontend that can join the same channel. Let us also enable this by including socket.js in our web/static/js/app.js which represents our web application:\n@@ -18,4 +18,4 @@ import \u0026#34;deps/phoenix_html/web/static/js/phoenix_html\u0026#34; // Local files can be imported directly using relative // paths \u0026#34;./socket\u0026#34; or full ones \u0026#34;web/static/js/socket\u0026#34;. -// import socket from \u0026#34;./socket\u0026#34; +import socket from \u0026#34;./socket\u0026#34; \u0026hellip;and then edit socket.js to have it join our new channel:\nsocket.connect() // Now that you are connected, you can join channels with a topic: -let channel = socket.channel(\u0026#34;topic:subtopic\u0026#34;, {}) +let channel = socket.channel(\u0026#34;scan:public\u0026#34;, {}) channel.join() .receive(\u0026#34;ok\u0026#34;, resp =\u0026gt; { console.log(\u0026#34;Joined successfully\u0026#34;, resp) }) .receive(\u0026#34;error\u0026#34;, resp =\u0026gt; { console.log(\u0026#34;Unable to join\u0026#34;, resp) }) We can then verify we have a working channel by going to the Phoenix web application at http://yourmachine.com:4000 (or try my server at https://padme.krampe.se:1443 ) and press CTRL-ALT-J (typically) to check the console where it should say Joined successfully. Wohoo!\nPhoenix channels in Evothings Link to heading Ok, but\u0026hellip; now we want to make the Evothings mobile app talk to this channel! Going back to our \u0026ldquo;BLE Multiscan\u0026rdquo; application we need to:\nAdd Phoenix channel support. Modify the app so that it uses this channel in pub/sub fashion. The javascript client side code for Phoenix channels is phoenix.js. We need to include this library in our Evothings app, but it is written in ES2015 (aka ES6 or ECMAScript 2015 or ECMAScript 6), the latest version of Javascript, and this isn\u0026rsquo;t fully supported by browsers yet so you must use a transpiler to make it work. Whatever one may think of the.. feature explosion in ES6 - it\u0026rsquo;s probably wise to start learning it.\nOur Evothings app is however written in plain ES5 so to avoid rewriting it we would like to use phoenix.js transpiled to ES5. Phoenix already has Brunch integrated which is a neat \u0026ldquo;build tool\u0026rdquo; for the web stuff, and it in turn is configured out-of-the-box to run the Babel transpiler on all js files in order to compile any ES6 code to ES5 (good ole Javascript).\nIn other words, we can already find a ES5-compiled version of phoenix.js in our filetree that we can copy and stuff into our mobile app.\n$ find . -name phoenix.js ./deps/phoenix/priv/static/phoenix.js ./deps/phoenix/web/static/js/phoenix.js The last one is the regular source code in ES6 and the first one is the Babel translated one in ES5 - which is the one we want. We copy it into our Evothings app:\n$ mkdir app/libs/phoenix $ cp ./deps/phoenix/priv/static/phoenix.js ./app/libs/phoenix/ \u0026hellip; and then we include it as a separate lib in index.html:\n\u0026lt;script src=\u0026#34;libs/jquery/jquery.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script src=\u0026#34;libs/evothings/evothings.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script src=\u0026#34;libs/evothings/ui/ui.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; +\t\u0026lt;script src=\u0026#34;libs/phoenix/phoenix.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script src=\u0026#34;app.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;/head\u0026gt; \u0026hellip; so we can require it at the top in app.js. Next up is modifying the application itself. Here are all modifications I made with explanations below.\n// JavaScript code for the BLE Scan example app. +Phoenix = require(\u0026#39;phoenix\u0026#39;) // Application object. var app = {}; // Device list. app.devices = {}; // UI methods. app.ui = {}; // Timer that updates the device list and removes inactive // devices in case no devices are found by scan. app.ui.updateTimer = null; app.initialize = function() { document.addEventListener( \u0026#39;deviceready\u0026#39;, function() { evothings.scriptsLoaded(app.onDeviceReady) }, false); }; app.onDeviceReady = function() { -\t// Not used. // Here you can update the UI to say that // the device (the phone/tablet) is ready // to use BLE and other Cordova functions. +\tconsole.log(\u0026#34;Creating Phoenix socket...\u0026#34;); + +\t// For this example I hard coded the host and port of my Phoenix application +\tvar socket = new Phoenix.Socket(\u0026#34;wss://padme.krampe.se:1443/socket\u0026#34;, +\t{ params: { token: \u0026#34;dummy\u0026#34; } }) + +\t// Nice with some logging in the Workbench when trying it all out +\tsocket.onError(function (err) { +\tconsole.log(\u0026#34;Error Phoenix channel: \u0026#34;+JSON.stringify(err) +\t)}); +\tsocket.onClose(function () { +\tconsole.log(\u0026#34;Closed Phoenix channel\u0026#34;) +\t}); +\tconsole.log(\u0026#34;Connecting...\u0026#34;); +\tsocket.connect(); + +\t// Now that we are connected we can join a channel with a topic. +\t// Let\u0026#39;s join the topic \u0026#39;scan:public\u0026#39; +\tapp.channel = socket.channel(\u0026#34;scan:public\u0026#34;, {}); +\tconsole.log(\u0026#34;Joining...\u0026#34;); +\tapp.channel.join().receive(\u0026#34;ok\u0026#34;, function (resp) { +\tconsole.log(\u0026#34;Joined successfully\u0026#34;); +\t}).receive(\u0026#34;error\u0026#34;, function (resp) { +\tconsole.log(\u0026#34;Unable to join\u0026#34;); +\t}); + +\t// Also register a handler for added devices +\tapp.channel.on(\u0026#34;scan:device\u0026#34;, function (msg) { +\tapp.phoenixReceive(msg); +\t}); + +\t// And start updating list +\tapp.ui.updateTimer = setInterval(app.ui.displayDeviceList, 500); }; // Start the scan. Call the callback function when a device is found. // Format: // callbackFun(deviceInfo, errorCode) // deviceInfo: address, rssi, name // errorCode: String app.startScan = function(callbackFun) { app.stopScan(); evothings.ble.startScan( function(device) { // Report success. Sometimes an RSSI of +127 is reported. // We filter out these values here. if (device.rssi \u0026lt;= 0) { callbackFun(device, null); } }, function(errorCode) { // Report error. callbackFun(null, errorCode); } ); }; +// Called when we get a device from Phoenix +app.phoenixReceive = function(msg) +{ +\t// Insert the device into table of found devices. + var device = JSON.parse(msg.body); +\tapp.devices[device.address] = device); +}; + +// Send a device back to Phoenix +app.phoenixSend = function(device) +{ +\tapp.channel.push(\u0026#34;scan:device\u0026#34;, { + user: \u0026#34;Arne\u0026#34;, + body: device + }); +}; + // Stop scanning for devices. app.stopScan = function() { evothings.ble.stopScan(); }; // Called when Start Scan button is selected. app.ui.onStartScanButton = function() { app.startScan(app.ui.deviceFound); app.ui.displayStatus(\u0026#39;Scanning...\u0026#39;); -\tapp.ui.updateTimer = setInterval(app.ui.displayDeviceList, 500); }; // Called when Stop Scan button is selected. app.ui.onStopScanButton = function() { app.stopScan(); app.devices = {}; app.ui.displayStatus(\u0026#39;Scan Paused\u0026#39;); app.ui.displayDeviceList(); -\tclearInterval(app.ui.updateTimer); }; // Called when a device is found. app.ui.deviceFound = function(device, errorCode) { if (device) { -\t// Set timestamp for device (this is used to remove -\t// inactive devices). +\t// Set timestamp for device, this is used to remove inactive devices. device.timeStamp = Date.now(); -\t// Insert the device into table of found devices. -\tapp.devices[device.address] = device; +\t// Report device to Phoenix backend. +\tapp.phoenixSend(JSON.stringify(device)); } else if (errorCode) { app.ui.displayStatus(\u0026#39;Scan Error: \u0026#39; + errorCode); } }; // Display the device list. app.ui.displayDeviceList = function() { // Clear device list. $(\u0026#39;#found-devices\u0026#39;).empty(); var timeNow = Date.now(); $.each(app.devices, function(key, device) { // Only show devices that are updated during the last 10 seconds. if (device.timeStamp + 10000 \u0026gt; timeNow) { // Map the RSSI value to a width in percent for the indicator. var rssiWidth = 100; // Used when RSSI is zero or greater. if (device.rssi \u0026lt; -100) { rssiWidth = 0; } else if (device.rssi \u0026lt; 0) { rssiWidth = 100 + device.rssi; } // Create tag for device data. var element = $( \u0026#39;\u0026lt;li\u0026gt;\u0026#39; +\t\u0026#39;\u0026lt;strong\u0026gt;\u0026#39; + device.name + \u0026#39;\u0026lt;/strong\u0026gt;\u0026lt;br /\u0026gt;\u0026#39; // Do not show address on iOS since it can be confused // with an iBeacon UUID. +\t(evothings.os.isIOS() ? \u0026#39;\u0026#39; : device.address + \u0026#39;\u0026lt;br /\u0026gt;\u0026#39;) +\tdevice.rssi + \u0026#39;\u0026lt;br /\u0026gt;\u0026#39; + \u0026#39;\u0026lt;div style=\u0026#34;background:rgb(225,0,0);height:20px;width:\u0026#39; + rssiWidth + \u0026#39;%;\u0026#34;\u0026gt;\u0026lt;/div\u0026gt;\u0026#39; + \u0026#39;\u0026lt;/li\u0026gt;\u0026#39; ); $(\u0026#39;#found-devices\u0026#39;).append(element); } }); }; // Display a status message app.ui.displayStatus = function(message) { $(\u0026#39;#scan-status\u0026#39;).html(message); }; app.initialize(); In lines 31-55 we create our Phoenix socket and join a channel on it In line 57-60 we register a handler for the topic \u0026ldquo;scan:device\u0026rdquo; In line 63 we start a timer to update our display list every 0.5 sec In line 93-98 we parse the incoming JSON and add a device in the list In line 100-107 we push the device JSON onto the same topic We remove line 120 and 130 since we use the timer all the time now regardless if scanning In line 143-146 we send the JSON to Phoenix instead of just adding it to the display list IMPORTANT: On line 34 you will need to stuff in your own ipname for your Phoenix server, and port. Or else you will connect to mine, which is of course just fine too :)\nNo magic going on here really, we simply push any discovered device as JSON back to Phoenix on the topic. And we also show any incoming devices on the same topic on the display list.\nSecure Websockets Link to heading When running the Evothings Viewer like we do, via Evothings Studio, the app is actually served via HTTPS to the viewer from Evothing\u0026rsquo;s proxy servers running in the cloud. So if the app is meant to connect to some other server (like our Phoenix server) using websockets, it needs to also use proper HTTPS, otherwise it will not work.\nSo we need to get our Phoenix to talk HTTPS with a proper cert, self signed doesn\u0026rsquo;t cut it for secure websockets.\nI first tried CACert.org, but that \u0026hellip; failed in various ways. Then someone hinted that StartSSL actually gives you ONE fully proper cert for free! And sure enough that worked great. So get a free one from them matching the ipname of your server - it was fairly easy to do.\nYou will however need to remove the pass phrase, but I solved that easily with:\nopenssl rsa -in ssl.key.bak -out ssl.key.nopass Then we can configure Phoenix to use this cert by modifying config/dev.exs:\n# watchers to your application. For example, we use it # with brunch.io to recompile .js and .css sources. config :multiscan, Multiscan.Endpoint, - http: [port: 4000], + url: [host: \u0026#34;padme.krampe.se\u0026#34;, port: 1443], + https: [port: 1443, + otp_app: :multiscan, + keyfile: System.get_env(\u0026#34;MULTISCAN_SSL_KEY_PATH\u0026#34;), + certfile: System.get_env(\u0026#34;MULTISCAN_SSL_CERT_PATH\u0026#34;), + cacertfile: System.get_env(\u0026#34;MULTISCAN_CERTFILE_PATH\u0026#34;)], debug_errors: true, code_reloader: true, cache_static_lookup: false, check_origin: false, watchers: [node: [\u0026#34;node_modules/brunch/bin/brunch\u0026#34;, \u0026#34;watch\u0026#34;, \u0026#34;--stdin\u0026#34;]] Of course you should use your own host and port on line 5 above. And then I added a run.sh that looks like this:\nexport MULTISCAN_SSL_KEY_PATH=$PWD/cert/ssl.key.nopass export MULTISCAN_SSL_CERT_PATH=$PWD/cert/ssl.crt export MULTISCAN_CERTFILE_PATH=$PWD/cert/sub.class1.server.ca.pem mix phoenix.server \u0026hellip; so in the local directory cert you need to place those three files from StartSSL. Then just run it and with some luck it will start serve on HTTPS :)\nTrying it out! Link to heading Now, for those approximate 3 people out there that bothered reading this far \u0026hellip; :) Time to see if it works!\nYou can try this out in different ways:\nRun your own app but still pointing at padme.krampe.se:1443 Run your own app pointing at your own server Start up at least two devices with the app, then if things work you should be able to start scanning on any of them and they should both quickly show the devices found. Note however that if others are using my server you will see their devices too. The following movie shows it working:\nWhat next? Link to heading Please give feedback in the comments below and I can adjust this article accordingly! You can also find me and the rest of the Evothings team at gitter or on #evothings at freenode.\nAn obious extension to this experiment here would be to add a web frontend to this in Phoenix so that you can just surf there to see all scanned devices in realtime, and of course throw some Ecto love at it to make some stuff persistent.\nHope you found this interesting!\nregards, Göran\n"},{"title":"Elixir Booming","permalink":"https://goran.krampe.se/2015/10/27/elixir-booming/","summary":"\u003cp\u003eIt seems like the \u003cem\u003e\u0026ldquo;damp cloth of Java\u0026rdquo;\u003c/em\u003e that has been plastered all over the programming landscape the last 20 years is finally being lifted. I admit, I do \u003cstrong\u003edislike Java \u0026hellip;immensely\u003c/strong\u003e. And not only on technical grounds, but even more based on what I perceive as it\u0026rsquo;s community worshipping complexity for it\u0026rsquo;s own sake. Of course IMHO.\u003c/p\u003e\n\u003cp\u003eThese days new and \u003cstrong\u003etruly interesting languages\u003c/strong\u003e are all over the place. \u003ca href=\"http://rust-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eRust\u003c/a\u003e\n and \u003ca href=\"http://go-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eGo\u003c/a\u003e\n are two examples with a lot of momentum, although I personally choose \u003ca href=\"http://nim-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNim\u003c/a\u003e\n over both.\u003c/p\u003e\n\u003cp\u003eAnd \u003ca href=\"http://pharo.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSmalltalk\u003c/a\u003e\n is still my \u0026ldquo;super productive dynamically typed\u0026rdquo; language of choice, but I just learned about a language that I \u003cstrong\u003ereally\u003c/strong\u003e think is going places\u0026hellip;\u003c/p\u003e","content":"It seems like the \u0026ldquo;damp cloth of Java\u0026rdquo; that has been plastered all over the programming landscape the last 20 years is finally being lifted. I admit, I do dislike Java \u0026hellip;immensely. And not only on technical grounds, but even more based on what I perceive as it\u0026rsquo;s community worshipping complexity for it\u0026rsquo;s own sake. Of course IMHO.\nThese days new and truly interesting languages are all over the place. Rust and Go are two examples with a lot of momentum, although I personally choose Nim over both.\nAnd Smalltalk is still my \u0026ldquo;super productive dynamically typed\u0026rdquo; language of choice, but I just learned about a language that I really think is going places\u0026hellip;\nErlang has always been on my todo list, and I did try once or twice but frankly, the language seemed a bit primitive. But anyone with any clue about Erlang also knows it is extremely strong in the area of robust, forever running and very scalable distributed systems.\nErlang got a revival with the new focus on highly distributed systems, especially the emerging NoSQL database systems - it fit like a glove. Riak from Basho is perhaps the most obvious example of these systems. And WhatsApp is the latest $19 billion poster child for the Erlang story.\nEnter Elixir Link to heading But now things are heating up significantly. In 2012 José Valim created Elixir , a new language targeting the Erlang VM. Elixir manages to be true to the core Erlang ideas and is very compatible with the Erlang eco system - but at the same time it brings a whole lot more to the party. And it is making a buzz for sure, even Joe Armstrong likes it (one of the core Erlang creators).\nJosé Valim comes from the RoR community, having been a core developer there, so a lot of the Ruby people, including Dave Thomas , are hopping aboard the Elixir express .\nAnd that inevitably brings us to the primary web framework of Elixir called Phoenix mainly developed by Chris McCord and reaching 1.0 just two months ago . Phoenix is picking up the challenge to create a \u0026ldquo;Rails killer\u0026rdquo; in Elixir and this presentation is one of the most informative on it .\nBut not only is Elixir and Phoenix attracting the interest of web developers that want a fresh air of truly stellar performance (especially compared to RoR) - it is also making a dent in the embedded world due to its extreme robustness and ability to do hot code deployment, see this presentation .\nThe more I read and browse the more I find. Real world success stories, books, blog articles - truly impressive given it\u0026rsquo;s only been approximately a year since the language hit 1.0! The IRC channel has more than 450 people, almost twice as much as Rust has, still half of Python or Go but let\u0026rsquo;s check again in a few months. ;)\nSeveral Erlang people tend to describe Elixir as a logical next step for Erlang , which means it is blending in with the already well established Erlang community. This is a big plus. As an example Elixir\u0026rsquo;s package manager is Hex but it can also do Erlang packages and may very well turn into the main package manager for the whole Erlang eco system.\nThe Boom Link to heading Given how it looks I think Elixir is about to go big. It is a stellar language for scalable systems and Phoenix brings it to the web arena leaving RoR completely in the dust performance wise. Elixir also utilizes all your cores (well, it\u0026rsquo;s what Elixir gets for free from running on BEAM), without the significant burden of the asynchronous \u0026ldquo;code mess\u0026rdquo; that NodeJS and similar asynchronous solutions has forced us to endure. And that pain didn\u0026rsquo;t give us multicore anyway!\nThis means Elixir has a great position to catch both the Rails and the Node developers with a superb offering. Javascript will still be king on the frontend (browser and hybrid mobile) for the foreseeable future, but on the server side I think all the dynamic web frameworks will get disrupted by Phoenix. This means typically all the frameworks for Node, Ruby and Python.\nPhoenix is also perfect for the new style of connected HTML5 apps - the modern web. Yeah, it\u0026rsquo;s funny, we are back to the client server architecture for sure. So does that scale? It sure as hell seems to . See Chris talking about what comes next in Phoenix .\nElixir has a lot of checkboxes checked:\nVery strong and vocal lead developers (José Valim, Chris McCord and more) Good tooling Growing list of packages Several evangelists It\u0026rsquo;s own conference It\u0026rsquo;s own web framework Several books published Natural path to both Rails and Erlang people Here is a nice terse introduction for the impatient . You can also read the official Getting Started , but it has evolved into more of a language manual.\nI am going to see if I can get my Raspberry Pi (that I got from my brother as a christmas gift) to run some Phoenix\u0026hellip;\n"},{"title":"Adding objects to Ni!","permalink":"https://goran.krampe.se/2015/09/25/adding-objects-to-ni/","summary":"\u003cp\u003eSo\u0026hellip; Ni has almost reached the point where I can see objects appearing. The following describes the design I \u003cstrong\u003ecurrently\u003c/strong\u003e have in mind, read it and tell me what you think so I can scrap it and start over ;)\u003c/p\u003e\n\u003cimg src=\"/ni/ni.png\" alt=\"Ni\" style=\"float:right; margin:0 0 1em 1em;\"\u003e","content":"So\u0026hellip; Ni has almost reached the point where I can see objects appearing. The following describes the design I currently have in mind, read it and tell me what you think so I can scrap it and start over ;)\nIntroducing Dictionary Link to heading Before we get to objects, we need something else - a Dictionary. A Dictionary is just a key/value collection - the name comes from Smalltalk, in many other languages they are called Map or HashTable and in Nim it\u0026rsquo;s called a Table. Rebol uses the word \u0026ldquo;Context\u0026rdquo;, and that is the word I have used so far in the Ni sources and articles. But nah, sorry Rebol, calling it a Dictionary makes it easier to understand IMHO.\nDictionaries and Blocks are the two primary plain data structures in Ni. Other more specialized collections would be constructed as objects (just like in Smalltalk) or added as a Ni extension. In this sense Ni is a bit like Javascript. It\u0026rsquo;s not purely OO as Smalltalk is, where both these are represented as objects. But IMHO as long as that fact doesn\u0026rsquo;t cause \u0026ldquo;gotchas\u0026rdquo; it\u0026rsquo;s fine.\nAs many languages before Ni has shown - having language syntax support for Dictionaries can be very useful.\nI earlier hinted on using curly braces { ... } for this, and I still think that\u0026rsquo;s more useful than using them as a second asymmetrical (thus nestable) string delimiter, as Rebol does. Also, we generally like to follow Nim when it comes to details like this.\nI kept brooding over this, what would be the best way to make it very readable and still fit in with The Way of the Ni Knights? First I was trying to mimic Javascript but it felt clumsy, then one morning it dawned upon me that the cleanest solution is the most obvious solution. And what is that then?\nWell, how about if we combine the characteristics of a Paren (has no Dictionary of bindings, and evaluates containing code, when evaluated, to a single result) and a Block (gets its own activation record when evaluated and thus has a Dictionary of bindings, but does not evaluate its code when evaluated, only when explicitly done so via do).\nAnd yes\u0026hellip; I should have read more Rebol - because creating objects in Rebol works quite similarly :)\nA Dictionary could then be created like this:\n{ a = 2 b = 3 } And it would evaluate immediately as a Paren does, but it would also (upon evaluation) create an activation record with a Dictionary, like a Block does. And when the evaluation is done, it would return that Dictionary as its value! It\u0026rsquo;s darn beautiful if you ask me. There is no need for special syntax inside the Curly, it\u0026rsquo;s just arbitrary Ni code like in a Block! Muuaahhahaa! Yeah, yeah, all you Rebolers think this is old stuff of course. ;)\nSo the above could also be done more explicitly using a block like this:\ndo [ a = 2 b = 3 bindings ] We need to use do to run the block since blocks do not evaluate by themselves, and the block ends with bindings which would return the local Dictionary of the activation record.\nA larger example:\nmyDict = { age = 46 interests = [programming boats badminton] name = \u0026#34;Göran\u0026#34; echo (\u0026#34;Just created \u0026#34; \u0026amp; name) # Remember, this is just code! } echo (myDict at: \u0026#39;name) echo (myDict at: \u0026#39;interests) Tada! So now we have Dictionaries.\nPunting on Modules Link to heading In Ni, lookups are done lexically \u0026ldquo;outwards\u0026rdquo; until we reach the root Context. The root Context is our global namespace. Modules is in many languages a hot topic. Ni tries to learn its ways before introducing a Module system, but it most likely will be something derived from Dictionary, or nothing at all :)\nIntroducing Object Link to heading A Dictionary is just a \u0026ldquo;plain datatype\u0026rdquo; or in other words, we can\u0026rsquo;t associate \u0026ldquo;methods\u0026rdquo; with it. We can define infix functions usable on Dictionaries of course, and at: is an example of that, but there is no polymorphic dispatch going on on the Ni level (but inside the interpreter we use Nim methods to gain polymorphism for builtin datatypes).\nLet\u0026rsquo;s first suppose that an Object in Ni is in essence a Dictionary but a bit different. It feels natural that an object can be modelled as a Dictionary to hold the \u0026ldquo;instance variables\u0026rdquo;. Just like we create Funcs from Blocks we could then create Objects from Dictionaries using an object word:\nrectangle = object { x = 0 y = 0 width = 0 height = 0 } This is an object that is quite silly, because it has no behavior. The idea of objects holding their own instance based behavior may look neat in theory but is pretty useless in practice I think. Most prototype based languages seem to evolve some kind of class mechanism to have shared sets of behaviors that we can reason about. Ni thus punts on any \u0026ldquo;instance based\u0026rdquo; lookup for behaviors, instead I am focusing on a mixin-style ordered lookup by making the object have a block of Traits:\nrect = object { traits = [Positionable Rectangle] x = 0 y = 0 width = 0 height = 0 } So in summary, we introduce an Object that we create using the object word that takes a Dictionary as input. This is an instance, not a class. The Dictionary can hold a special key traits which has a block of Traits in order. A Trait is the closest we get to a class in Ni, but it defines no structure and it also doesn\u0026rsquo;t inherit from other Traits, it\u0026rsquo;s just a Dictionary of named Funcs really.\nSo a more complete example could look like:\n# A set of behaviors for a Point that has an x and y # We use capital letter for Traits. The trait word takes # a Context and creates a Trait for us. Point = trait { x = func [.x] # A getter, note the .-scoping y = func [.y] x:y: = func [:.x :.y] # A setter, note the .-scoping moveX:y: = func [self moveX: :dx self moveY: :dy] # Self calls moveX: = func [.x = .x + :dx] moveY: = func [.y = .y + :dy] } # One more Trait, a set of behaviors for a Rectangle with width and height Rectangle = trait { area = func [.width * .height] extent: = func [:extent .width = extent x .height = extent y] } # An object which uses a single Trait origo = object { traits = [Point] x = 0 y = 0 } # An object which uses two Traits, lookup is in order so conflicts are just shadowed # If you wish to resolve conflicts you create yet another Trait and put it first patching it up rect = object { traits = [Point Rectangle] x = 0 y = 0 width = 0 height = 0 } # Creating new objects is easily done copying an existing object rect2 = copy rect # And you can always make funcs taking arguments returning new objects # just like you typically do in Nim instead of constructors. newRectangle = func [ :x :y :w :h object { traits = [Point Rectangle] x = ..x # This will refer to the x argument in the func y = ..y width = ..w height = ..h } ] # And then we can easily call it, this time using Rebol # style argument passing instead of a Smalltalk style keyword # message. As one sees fit. rect3 = newRectangle 100 100 640 400 # Polymorphic dispatch, both objects respond to the getter x [rect origo] do: [echo :each x] There are many details here one can discuss, but some thoughts:\nI find the above object model to feel less \u0026ldquo;confusing\u0026rdquo; than a delegation model, still need to bang on it for real though. I avoid instance specific behaviors since I doubt they are useful. A Trait is also created from a Dictionary. Purely a set of behaviors, clean, simple. I reserve the key traits for the slot in the object holding the Block of Traits. Fine! :) Lookup is by order, thus conflicts are ok, the Trait coming first simply wins. Inheritance and composition can be done in many ways here using copying of prototypes and manipulating the traits block Not inheriting structure doesn\u0026rsquo;t feel like a great loss, and actually, since an Object is basically a Context - inheritance of structure can also be done via a simple initialize pattern letting the Traits in order initialize their variables. Ability to call \u0026ldquo;super\u0026rdquo; etc, well, it can also be added, although I am curious if one can avoid classic OO design where it easily becomes something you want to do. I am really interested what kind of feedback I can get on this, a lot of other developers/language designers out there are much more educated than I am!\nObject dispatch Link to heading But how is the dispatch done?\nI think I will try making Object nodes affect the lookup of the word coming right after. This means methods are strictly called with the receiver object on the left.\nWhen Ni first encounters rect it will notice it\u0026rsquo;s an Object, remember that, and continue to the next node. Before the regular lookup of the next word, we first need to let rect look it up among its traits. If we find a func we call it with self bound to rect, thus methods like this overrides any available infix func we could have found. If we didn\u0026rsquo;t find anything, we continue normal lookup of the word since it may be a regular non polymorphic infix function. Now we have the first seed of an Object model! Will it work? Haven\u0026rsquo;t got a clue. Time to hack it. But\u0026hellip; it does look doable and I think I like it.\n"},{"title":"Ni","permalink":"https://goran.krampe.se/ni/","summary":"\u003cp\u003eThe language formerly known as \u0026ldquo;Ni\u0026rdquo; is now called \u003ca href=\"spry\" \u003eSpry\u003c/a\u003e\n.\u003c/p\u003e","content":"The language formerly known as \u0026ldquo;Ni\u0026rdquo; is now called Spry .\n"},{"title":"Ni design decisions!","permalink":"https://goran.krampe.se/2015/09/23/ni-design-decisions/","summary":"\u003cp\u003eSo\u0026hellip; my little Ni language got some attention since it was first \u003ca href=\"https://news.ycombinator.com/item?id=10235688\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eon Hackernews\u003c/a\u003e\n, then \u003ca href=\"http://www.theregister.co.uk/2015/09/18/we_are_the_knights_who_code_ni/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eTheRegister\u003c/a\u003e\n, all over Twitter and also \u003ca href=\"https://www.reddit.com/r/programming/comments/3lfpym/ni_a_language_influenced_by_smalltalk_written_in/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eReddit\u003c/a\u003e\n.\u003c/p\u003e\n\u003cp\u003eBut I think it managed to come relatively unscathed out of it, although it \u003cstrong\u003eREALLY is pre-alpha-not-even-complete-eats-your-harddrive early\u003c/strong\u003e and you know, I really have no idea if it ever will go the distance since it takes quite a bit of work to get a language to actually be used. But I am going to stick with it.\u003c/p\u003e\n\u003cp\u003eAnyway, I have been experimenting with \u0026ldquo;arg words\u0026rdquo; and \u0026ldquo;lookup scoping\u0026rdquo; while thinking about how to add objects, and a few other things. This article doesn\u0026rsquo;t introduce how I want to do objects, but the next one does (I split it in two). This article however covers a bunch of loose ends and my ideas on how to tackle them in Ni. And I will try to make this understandable even if you don\u0026rsquo;t know Ni. ;)\u003c/p\u003e","content":"So\u0026hellip; my little Ni language got some attention since it was first on Hackernews , then TheRegister , all over Twitter and also Reddit .\nBut I think it managed to come relatively unscathed out of it, although it REALLY is pre-alpha-not-even-complete-eats-your-harddrive early and you know, I really have no idea if it ever will go the distance since it takes quite a bit of work to get a language to actually be used. But I am going to stick with it.\nAnyway, I have been experimenting with \u0026ldquo;arg words\u0026rdquo; and \u0026ldquo;lookup scoping\u0026rdquo; while thinking about how to add objects, and a few other things. This article doesn\u0026rsquo;t introduce how I want to do objects, but the next one does (I split it in two). This article however covers a bunch of loose ends and my ideas on how to tackle them in Ni. And I will try to make this understandable even if you don\u0026rsquo;t know Ni. ;)\nArgwords design mistake Link to heading Argwords (Ni\u0026rsquo;s mechanism for accessing arguments inside a function) as they stand today are neat but suffer from an embarrassing \u0026ldquo;design mistake\u0026rdquo;. Simple blocks work fine, for example like these, similar to Smalltalk:\n[:a :b a + b] [:a \u0026gt; :b] The first one seems \u0026ldquo;just like Smalltalk\u0026rdquo;. It looks like the arguments are declared at the beginning, but note that there is no separator between those \u0026ldquo;declarations\u0026rdquo; and the rest of the code like Smalltalk has (the |). This is because an argword in Ni is an operation, not a declaration. So :a means \u0026ldquo;pull in the next argument from the callsite (evaluating it first), store the value in local variable a\u0026rdquo; and the value of :a is the argument pulled in.\nThis means the second example works fine, since the value of :a is whatever we pulled in, and since the argwords can come anywhere in the block, we can call the \u0026lt;-word immediately like that.\nSo what is the mistake?\nWell, let\u0026rsquo;s say we do something like [ifelse (:a \u0026gt; 0) [a + :b] [0]]. It says \u0026ldquo;pull in a and if it\u0026rsquo;s bigger than zero, pull in b and add them together and return that, otherwise don\u0026rsquo;t pull in a second argument and just return 0\u0026rdquo;. One can definitely question the usefulness of such dynamic arity :) but anyway, let\u0026rsquo;s see what nirepl says:\ngokr@yoda:~/nim/ni$ nirepl We are the knights who say... Ni! Enter shrubbery... eh, code and an empty line will evaluate previous lines, so hit enter twice. do [ifelse (:a \u0026gt; 0) [a + :b] [0]] 1 2 Oops, sorry about that: Can not evaluate 1 + [0] Hehe, what? Ahh\u0026hellip; so :b tries to pull in the next argument at the call site, but this is a nested block so it doesn\u0026rsquo;t try to pull in 2 but instead tries to pull in \u0026ldquo;whatever comes next in the block where this block is defined\u0026rdquo;. And that happens to be the else-block of ifelse\u0026hellip; ooops. And yeah, Ni doesn\u0026rsquo;t have any proper error model yet, any ideas on that is appreciated.\nSo the current design issue means\u0026hellip; argwords in nested blocks will not work as expected - since we use blocks for control structures! It means that you would need to rewrite this example as [if (:a \u0026lt;= 0) [0] a + :b] which would work fine, since now :b is not in a nested block.\nI don\u0026rsquo;t have a good idea on how to make this work when nested, perhaps I will let this one just be a \u0026ldquo;language-gotcha\u0026rdquo; for now.\nScoped lookup Link to heading One thing I am experimenting with in Ni, which doesn\u0026rsquo;t exist in either Rebol (I think) or Smalltalk, is different variants of lookups for words.\nCurrently, regular word lookup starts by looking in the local scope, then in the outer lexical scope and outwards out to the root activation of the interpreter (global scope). This is the default lookup which means you have shadowing on all levels. But then one can already use two different prefixes to change that behavior:\n..banana - similar to filepaths this means only look in nearest outer lexical scope .banana - similar to filepaths this means only look in local scope The idea is to use this both for access and left side in an assignment. BUT\u0026hellip; I am having regrets, I think I will change it to:\nbanana - start in local and go all the way out for access. Assignment however is local only. .banana - only access and assign in \u0026ldquo;self\u0026rdquo; which typically will be bound to an object or module. This is instance variable access. ..banana - start in the \u0026ldquo;outer\u0026rdquo; scope and go all the way out. Both for access and assignment. So the default scoping, x without a prefix, will work fine for local variables, arguments and other things outside in the outer scopes. When assigning it will however always be in the local scope.\nFor instance variables in objects you will have to use .x, both for access and assignment. So those are explicitly different from all other variables, which I think is good in a language like Ni where we do not declare any variables. See upcoming article for more on Objects.\nNOTE: Since do not declare the names of variables - typos can only be discovered via heuristics, like \u0026ldquo;never assigned to nor an argument in this function\u0026rdquo; or \u0026ldquo;assigned to but never used\u0026rdquo; etc.\nFinally using ..x we are basically depending on an external environment to define x for us. It\u0026rsquo;s kinda like \u0026ldquo;I wish for an x\u0026rdquo; and we presume someone will make sure it\u0026rsquo;s out there somewhere. Exactly what \u0026ldquo;outer\u0026rdquo; scope means may be different depending on context. In a Func, it\u0026rsquo;s just in the defining outer scope.\nIntroducing undef Link to heading One other thing. I am considering introducing undef in addition to nil. Smalltalk suffers from its fair share of DNUs (doesNotUnderstand exception) due to variables being nil, most often not having been initialized to a proper value. But quite often in Smalltalk nil is also used as a proper value meaning \u0026ldquo;no value\u0026rdquo;, in that case it doesn\u0026rsquo;t mean \u0026ldquo;not set\u0026rdquo;. Thus separating undef from nil seems like a useful idea.\nSo if a word evaluates to nil there is at least a binding for it, but it has nil as its value. If a word evaluates to undef there was no binding found at all. I would like a short and punchy name though, undef is quite boring. Perhaps eki? :)\nExclamation point and question mark Link to heading In Rebol question marks are used as the last character of words to functions that evaluate to a boolean. Ruby does something similar I think and it\u0026rsquo;s a good thing, so Ni adopts that. There is however nothing special about the ?-character, it\u0026rsquo;s just a convention.\nThe exclamation point is used in Rebol as a marker of a datatype word. Rebol has lots of datatypes and likes to easily test values if they are of a certain datatype. One can also add type declarations of arguments to functions, although they are checked only at runtime. Ni is more Smalltalk-like and it seems to me that relying on polymorphism is more sound. Smalltalk code very seldom tests like that, and if it\u0026rsquo;s done we typically frown upon it. This makes the ! free for some other use or convention, ideas welcome.\nThe word consisting solely of ? could be used to test if a word is defined, so banana ? would be the same as banana != undef.\nIndexing and refinements Link to heading Also, two other issues that I really haven\u0026rsquo;t given proper thought:\nIndexing. In Nim you do x[1] and x[1] = 2 but in Smalltalk you use messages instead like x at: 1 or x at: 1 put: 2. Rebol refinements. In Rebol this can also double for indexing so the above would be x/1 and x/1 = 2. Otherwise Rebol uses words for indexing similar to Smalltalk. For the moment I consider going the Smalltalk route for indexing, since that works already and even though it\u0026rsquo;s \u0026ldquo;longer to type\u0026rdquo; it works fine in Smalltalk. It also honours encapsulation.\nRefinements in Rebol are kinda slick. They are used in two different ways - either as \u0026ldquo;indexing\u0026rdquo; or \u0026ldquo;member access\u0026rdquo;, or as a way to pass \u0026ldquo;flags\u0026rdquo; or optional arguments to functions. Smalltalk works without explicit member access from the outside, you need a setter or getter and that seems fine to me and ensures encapsulation. I also think foo/bar looks kinda odd to read for member access or indexing.\nThe flags to functions and optional arguments seems useful though and can be likened with the --opt that Unix uses. The obvious advantage is that they are boolean in nature, so shorter to write /short instead of short: true and they can also appear in any order and they are optional.\nSmalltalk does not have anything resembling this, there you often end up with a fairly clumsy approach with many similar keyword messages with various subsets of keywords, each calling the complete one with all keywords, supplying default values for those missing.\nI am more of a Linux than a Windows guy, and I don\u0026rsquo;t really like the \u0026ldquo;path\u0026rdquo; usage of refinements in Rebol. One idea is then to introduce a new kind of word: an option word. They would start with - (and be more than 1 character long so we can still have - for \u0026ldquo;minus\u0026rdquo;) and they would evaluate to themselves. The magic would however be in the mechanism of argwords, when an argword is evaluated, and it instead pulls in an option-word, it would:\nGobble it up and create a local binding for the option word to true Continue pulling to get a \u0026ldquo;real\u0026rdquo; argument This means option words must come before an argument, otherwise they will not be pulled in.\nExample:\nplus = funci [:a :b if hhgttg ? [return 42] # hhgttg is available as a local word if negated ? [return ((a + b) ..negated)] # Note how we need to use ..negated in order to avoid the local shadow return a + b] 1 plus -hhgttg 3 # When plus is pulling b it will also pull in -hhgttg 1 plus 3 1 plus -negated 3 One can also imagine optional arguments (where the value is something else than true) like Rebol has by simply using a ::\nconcat = funci [:a :b if separator ? [return a \u0026amp; separator \u0026amp; b] return a \u0026amp; b ] \u0026#34;bar\u0026#34; concat \u0026#34;foo\u0026#34; \u0026#34;bar\u0026#34; concat -separator: \u0026#34;, \u0026#34; \u0026#34;foo\u0026#34; Now we quickly realize that infix functions taking only one regular argument will have issues with passing optional arguments\u0026hellip; Options work, but not optional arguments since they would be pulled in \u0026ldquo;backwards\u0026rdquo;. And another thing, if you haven\u0026rsquo;t yet pulled all arguments you are not sure if you have pulled all options\u0026hellip; In other words, if your function offers options, it should probably start by pulling in all arg words like concat does above.\nOk, let\u0026rsquo;s chalk these oddities up as \u0026ldquo;language warts\u0026rdquo; for now. :)\nReflection Link to heading A number of words could be used to access and manipulate the internal machinery of Ni, like the activation stack and the current scope. Smalltalk has superb power by reifying the stack and making it available via the pseudo variable thisContext so doing something similar seems obvious.\nself - the nearest outer Object. This is mainly used for calling methods on self and passing self as argument, since state is accessed via .-scoping. There is no super concept. context - the nearest Context which can be the Context inside a function. It enables reflection on what locals are defined etc. activation - the current activation record. This would be the same as thisContext in Smalltalk (since Smalltalk calls them \u0026ldquo;contexts\u0026rdquo;). I will start with these I think.\nUntil next time, happy coding\n"},{"title":"Guts of Ni","permalink":"https://goran.krampe.se/2015/09/22/guts-of-ni/","summary":"\u003cp\u003eThis article describes some core parts of the current implementation of the Ni (now known as \u003ca href=\"/spry\" \u003eSpry\u003c/a\u003e\n) language. It\u0026rsquo;s not a tutorial, introduction or manual. It\u0026rsquo;s in \u003cstrong\u003efact kinda incoherent - but so is Ni\u003c/strong\u003e :)\u003c/p\u003e","content":"This article describes some core parts of the current implementation of the Ni (now known as Spry ) language. It\u0026rsquo;s not a tutorial, introduction or manual. It\u0026rsquo;s in fact kinda incoherent - but so is Ni :)\nThe parser Link to heading The Ni parser is a straight forward hand made recursive descent parser. Hmmm, now that I look closer I realize it\u0026rsquo;s not recursive. Its just a very simple while loop character by character and maintaining some state. It should be easy to read and understand and given that the grammar is so simple, it hasn\u0026rsquo;t changed much lately. It could probably be made faster by using more procs and less methods, but it\u0026rsquo;s probably plenty fast since the grammar is so simple.\nThe parser constructs an AST consisting of instances of subclasses of Node . A Node is a regular ref object which is Nim terminology for a GC controlled object allocated on the heap. Its worth noting that the parser can be used alone without the interpreter, but the ni module (the interpreter) obviously depends on the parser module.\nNodes, Nodes\u0026hellip; Link to heading In Ni everything is a Node, but they come in different families:\nValues - fundamental \u0026ldquo;things\u0026rdquo; typically represented internally by the corresponding Nim type Words - the bread and butter of Ni, kinda like Smalltalk Symbols but have different prefixes making them behave differently Composites - the three base collections of Ni: Blocks, Contexts (Context not implemented yet) and Parens. Derived composites - these are created from a Composite, like a Func or an Object (Object not implemented yet). Values in Ni are not Ni objects (although they are indeed Nim objects) like in Smalltalk. They can instead be viewed as fundamental datatypes, but the Ni interpreter is designed so that you can add more of these in separate extension modules.\nWords are pervasive in the language, just like messages are pervasive in Smalltalk. They are kinda like variables in other languages, but using different prefixes the word behaves differently.\nComposites are fundamental collections and they are supported by specific literal syntax in the parser, [], {}, () .\nFinally, derived Composites are things one can create using a Composite as input. A Func is a function and it\u0026rsquo;s created from a Block. Objects are yet to be implemented.\nValues Link to heading All atomic values are wrapped using one subclass of Node for each kind, and currently we have: int, float, string, bool and nil. The values true, false and nil are represented with three singleton Values that are held by the interpreter . Those three singletons are bound to the words true, false and nil in the root context, which is the global namespace.\nNew kinds of values can relatively easily be added to Ni since I intentionally made the parser be pluggable for this. However I do not like the abundance of builtin types that Rebol/Red has, it feels like a mistake to hardwire so much into the language itself. But this way we are free to experiment with such extension modules.\nWords Link to heading Ni uses the term \u0026ldquo;word\u0026rdquo; much like Rebol does. There are however quite a few differences in what kinds of words Ni supports. A word is just a string, but it\u0026rsquo;s wrapped in a Word node and there are a number of different subclasses of Word which behaves differently and use different prefixes.\nEvalWord: The most common kind of word, no prefix. All eval words delegates evaluation to whatever it is bound to. In this way they act much like variables do in most other languages. LitWord: A literal word. Uses the '-prefix and is used when one wants to refer to the word as a value itself. Evaluates to itself. GetWord: Uses the ̂^-prefix. The get words do not delegate evaluation, instead they skip evaluation and \u0026ldquo;evaluate\u0026rdquo; to whatever it is bound to. EvalArgWord: Used to \u0026ldquo;pull in\u0026rdquo; arguments to Funcs, uses :-prefix. Evaluates the argument in the callsite context and pulls in the result, this is like \u0026ldquo;normal\u0026rdquo; argument passing in most languages. GetArgWord: Uses the :^-prefix and evaluates to the argument itself, the AST node. No evaluation of the node is made. This enables Ni functions to manipulate the AST. All words (well, currently only EvalWords and GetWords, but I should make it work for ArgWords and LitWords too) can also, just before the word itself, be additionally prefixed with . or ... This affects lookup and is similar to how one refers to the current or parent directory in Unix. The rules I have in mind currently goes like this:\n..x: assignment and lookup is in the nearest outer lexical environment only. .x: assignment and lookup is in the local context only. x: assignment and lookup is in the local context, but lookup continues outward to the surrounding lexical environment and beyond. I have been mulling these rules over, but I think this logic would make it fairly reasonable. Any feedback appreciated!\nComparing with Rebol. As far as I know the . and ..-prefixes does not have a counterpart in Rebol. Rebol has get words and eval words, but uses :-prefix instead of ^-prefix for get words. The reason Ni deviates is to use : for arg words instead, mimicking Smalltalk block syntax. Rebol does not have arg words at all, but Rebol does have set words which Ni does not have (again to support keywords). Ni instead implements assignment as a primitive infix function.\nI also experimented earlier with bindings etc, but currently Ni doesn\u0026rsquo;t work like that. Exactly how different environments can be used dynamically - is still an open design question. Scoping is however mainly lexical but I can imagine mechanisms to control this, and also reification mechanisms in order to reflect on and manipulate the activation record spaghetti stack .\nComposites Link to heading There are three different composites in Ni, each formed by literal syntax [], () and {} respectively. These are called Blocks, Parens and Contexts.\nBlock and Paren is a wrapped seq of Nodes, seq being the dynamic array type of Nim. Currently they differ only in behavior since Parens evaluate by evaluating its child nodes one by one and returning the last result. Blocks just evaluate to themselves. To evaluate a Block as code you need to explicity do so using the do word.\nContexts are being implemented. A Context has a Nim Table internally making it the fundament of both objects and \u0026ldquo;Dictionaries\u0026rdquo;, much like in Javascript.\nObjects are being implemented and are fundamentally like Contexts, but with special evaluation behavior.\nRelying on Nim Link to heading The Ni interpreter tries to be very simple and reuses as much of Nim\u0026rsquo;s machinery as possible:\nA call in Ni results in a call in Nim. This means Ni maintains no call stack of its own. Ni has no memory model of its own, we use Nim\u0026rsquo;s very capable garbage collected memory model. Ni is a plain interpreter, not a JIT. The emphasis is instead on hackability, portability but also very much mixing with Nim. Ni primitives are Nim procs. It\u0026rsquo;s very easy to bind words to primitive procs in Nim. Dynamic dispatch in Ni (for Values) relies on dynamic dispatch in Nim, methods. Multiple dispatch is also used for number coercions and similar. Nim has very strong macro mechanisms which I hope to eventually use to generate glue code to expose Nim libraries in Ni. The things described in this article tend to evolved from day to day, but hopefully this better explains a bit about how Ni is constructed!\n"},{"title":"Who says Ni?","permalink":"https://goran.krampe.se/2015/09/16/who-says-ni/","summary":"\u003cp\u003eNi is my \u003ca href=\"/spry\" \u003eown little language\u003c/a\u003e\n heavily influenced by \u003ca href=\"http://www.world.st\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSmalltalk\u003c/a\u003e\n but also other sources like Rebol, Forth, Lisp, Self and Nim. Ni is a bit strange, but it\u0026rsquo;s not academic and really meant to become something useful.\u003c/p\u003e\n\u003cp\u003eSo put on your helmet and let me take you to the shrubbery\u0026hellip;\u003c/p\u003e","content":"Ni is my own little language heavily influenced by Smalltalk but also other sources like Rebol, Forth, Lisp, Self and Nim. Ni is a bit strange, but it\u0026rsquo;s not academic and really meant to become something useful.\nSo put on your helmet and let me take you to the shrubbery\u0026hellip;\nI love Smalltalk - the language that pioneered OO back in the 1980s and is still very much alive . But what makes Smalltalk so great? Trying to put my finger on it, here is a list:\nClosures and non local return for control structures. Low level types don\u0026rsquo;t get in my way (numbers for example) Easy and quick manipulation of collections. Easy readable keyword syntax, everything is an expression etc, gives great power in expressing code. The object model is easy to reason about and picture mentally, doesn\u0026rsquo;t get in your way. Fully reflective with live coding, inspectors, debuggers, while-we-run etc Cross referencing. All senders, implementors. All accesses to ivar, all references to class etc In making Ni I am striving to cover these bases and some of the fundamental pieces are there already, like closures and non local return.\nNi comes in two modules, the parser (500 loc) and the interpreter (750 loc). The parser produces an AST which is also the internal representation of data in Ni. The interpreter then interprets the AST. Ni is written in Nim and thus compiles and runs on basically any platform supported by C. There is a trivial REPL (70 loc).\nA taste of Ni Link to heading In Smalltalk 99% of our collections are OrderedCollection and Dictionary. It does make sense to give these two as good treatment as possible in a new language, I think Javascript and JSON etc have shown us the importance of this. Smalltalk, while having very strong collections, is actually kinda weak when it comes to literal syntax for these two fundamental data structures. Ni tries to remedy that.\nFor the ordered sequence, Ni is inspired by Rebol/Lisp and has the \u0026ldquo;Block\u0026rdquo; as the fundamental data structure. It\u0026rsquo;s like an OrderedCollection, and uses square bracket [1 2 3] syntax. And yes, it\u0026rsquo;s also the same syntax for code blocks because Ni is homoiconic. This means that code and data share the same representation, just like in Lisp/Rebol. So in Ni we can do:\ncode = [3 + 1] # This is a block with 3 elements code at: 2 put: 4 # Stuff the number 4 as the last element, we use positioning from 0 echo do code # Prints out 7 In the above code we can immediately note that yes, Ni is dynamically typed and assignment is done via =. Assignment is actually a function call, but let\u0026rsquo;s ignore that detail for now. Second line shows that Ni supports keyword syntax for multiple argument functions (like Self and Smalltalk), but it\u0026rsquo;s actually implemented as syntactic sugar in the parser. The second line can thus just as well be written like:\ncode at:put: 2 4 Which in a C-ish language can be read as:\ncode.at:put:(2, 4) This works since \u0026ldquo;:\u0026rdquo; is allowed in function names but they are given special treatment by the parser when they appear as the last character in a token.\nAnother interesting detail is that lines have no statement separator, but Ni does NOT use line endings or indenting to infer semantic meaning, so the code can actually be written without line endings like this too:\ncode = [3 + 1] code at: 2 put: 4 echo do code And it would still work the same, funky indeed. And yes, the conclusion is that whitespace is both insignificant (new lines don\u0026rsquo;t matter, all kinds of whitespace is just whitespace) and very significant (whitespace is used as token separator) in Ni, 3+4 is not the same as 3 + 4.\nBut let\u0026rsquo;s get back to Blocks. Not only are they both code and dynamic arrays, they also do double duty as streams since they have an embedded position \u0026ldquo;cursor\u0026rdquo;, just like in Rebol. This means iteration and streaming over Blocks is trivial:\nblock = [1 2 3] # Lets loop over it manually using the internal position block reset # Set position back to 0 [block end?] # We call an infix function called \u0026#34;end?\u0026#34; with block as argument whileFalse: # We call an infix function called \u0026#34;whileFalse:\u0026#34; taking two blocks [echo block next] # We call an infix function called \u0026#34;next\u0026#34; to get next element and echo it Implementing select: Link to heading The above looks silly for practical use, but we have what we need to easily implement Smalltalk select:. Let\u0026rsquo;s first learn some other details. When we run a Block - an activation record is created to hold the local environment of the block - in other words, a closure. We can also permanently associate such a Context ..no, that was wrong. A Func adds in particular a reference to the lexical parent activation, and a boolean flag showing if this is an infix function or not. A Func is created from a Block using the func function (tihi!):\nmyfunc = func [:a + :b] # \u0026#34;func\u0026#34; takes the block as an argument and returns a Func echo (myfunc 3 4) # Should print 7, parenthesis are used since echo is not eager. Here we also introduce another oddity of Ni, so called \u0026ldquo;arg words\u0026rdquo;. An arg word begins with a : and when evaluating :a Ni will pull in another argument from the call site and store it locally in a and that\u0026rsquo;s also the value of :a. It\u0026rsquo;s reminiscent of Smalltalk, but note that this is not a declaration, it\u0026rsquo;s actually an operation that can appear anywhere in the block. This means we can write extremely short lambdas like the above and we can also handle variable number of arguments.\nAs was seen above we can also make infix functions in Ni, using funci. This means the first arg word will pull from the left side at the call site:\nplus = funci [:a + :b] echo (3 plus 4) # Should print 7 since a is \u0026#34;pulled in from the left\u0026#34; Ok, let\u0026rsquo;s finish this little article by implementing the venerable Smalltalk select: through adapting the above code into an abstraction:\nselect: = funci [:blk :pred result = [] blk reset [blk end?] whileFalse: [ n = (blk next) if do pred n [result add: n]] return result ] [1 2 3 4] select: [:each \u0026gt; 2] # This will happily evaluate to \u0026#34;[3 4]\u0026#34; The above implementation of select: in Ni is simply an infix Func taking two Blocks as arguments, blk and pred. The first block (the \u0026ldquo;receiver\u0026rdquo;) is the block we want to iterate over. The second block is a code block taking one argument that should evaluate to true for those elements we are meant to filter out.\nThe body of select: first assigns an empty new Block to a local word (like a variable) result. Then it uses the builtin positioning of blk to loop over it, pluck out the next element and call pred using do (like sending #value in Smalltalk) to decide if we should add it to result. if is yet again a primitive function taking two arguments, first a boolean and second a block to evaluate if true. true, false and nil are words bound to known singletons just like in Smalltalk. At this point the pattern is quite clear - all control structures in Nim are functions, either primitive ones implemented in Nim and bound to words, or functions written in Ni.\nFinally we return the result, return is actually a primitive function, as almost everything is in Ni. The final line shows usage, and as you can see it looks very similar to Smalltalk or Self.\nGoing forward Link to heading Ni is evolving and it doesn\u0026rsquo;t do objects yet but I think Ni already shows (as Rebol already also has shown to some extent) that you can have a Smalltalk-ish language that is at the same time homoiconic and deeply functional. A bit of structure using blocks, a bit of syntactic sugar enabling keyword syntax, a bit of semantics to be able to do non local returns (yes! Ni has those too, so detect: is similarly easy to implement) and\u0026hellip; well, we have something new and interesting!\nAnd oh, it\u0026rsquo;s of course not only homoiconic but as examples above show - Ni is 100% live too, everything can change at runtime. And given that it mixes nicely with Nim that in turn easily can wrap and use C/C++ libraries - we have a new Smalltalkish language with an interesting twist.\nBeing written and easily embeddable in Nim makes Ni a great citizen in the C/C++ language eco system. Making a binary executable is trivial. Making a dll is also trivial. And finally, Nim has very interesting capabilities when it comes to multiple native threads and parallell computation, an area where we as Smalltalkers haven\u0026rsquo;t seen much action. Native GUIs? No problem, Nim can already do them.\nHope you liked this little peak into Ni!\n"},{"title":"Nim and super","permalink":"https://goran.krampe.se/2015/05/06/nim-and-super/","summary":"\u003cp\u003eAs I described in \u003ca href=\"/2014/10/29/nim-and-oo\" \u003ethe\u003c/a\u003e\n \u003ca href=\"/2014/10/31/nim-and-oo-part-ii\" \u003eearlier\u003c/a\u003e\n \u003ca href=\"/2014/10/31/nim-and-oo-part-iii\" \u003eposts\u003c/a\u003e\n Nim didn\u0026rsquo;t support \u0026ldquo;super calls\u0026rdquo; when using \u003cstrong\u003emethods\u003c/strong\u003e instead of statically bound \u003cstrong\u003eprocs and generics\u003c/strong\u003e. My article caused a little bit of discussion around this on IRC and Andreas decided to implement the mechanism he already had planned - but had not fully decided a good name for.\u003c/p\u003e\n\u003cp\u003eThe other day Nim 0.11.2 \u003ca href=\"http://nim-lang.org/news.html#Z2015-05-04-version-0-11-2-released\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ewas released\u003c/a\u003e\n and it includes this mechanism. Let\u0026rsquo;s have a look how it works in my sample code\u0026hellip;\u003c/p\u003e","content":"As I described in the earlier posts Nim didn\u0026rsquo;t support \u0026ldquo;super calls\u0026rdquo; when using methods instead of statically bound procs and generics. My article caused a little bit of discussion around this on IRC and Andreas decided to implement the mechanism he already had planned - but had not fully decided a good name for.\nThe other day Nim 0.11.2 was released and it includes this mechanism. Let\u0026rsquo;s have a look how it works in my sample code\u0026hellip;\nInstead of calling it static_call - implying that the call resolution is made at compile time statically, the name ended up as procCall - implying the call resolution is simply done just like its done for procs. Same, same - different words. To put it another way, even though we are calling a method, let the static types of the arguments decide which method to call, not the actual runtime types.\nA bit of repetition from the earlier articles - today you can select among overloaded procs to call by using type conversion, so if you want to call myProc that takes an argument of type A when you have an object of type B in your hand (B being a sub type of A), you just do myProc(A(b)).\nThis is called a type conversion and can be viewed as a type safe cast, it only works if its safe to do it. Nim also has cast but generally its something you should only use if you know what the heck you are doing. :)\nNow\u0026hellip; methods don\u0026rsquo;t rely on static typing - they resolve based on the actual runtime type of the objects - that\u0026rsquo;s their whole reason for existing and this is essential in supporting more complex OO code. So the type conversion technique in itself only works for selecting among overloaded procs, not methods.\nBut now, with the addition of procCall we can call overloaded methods using the exact same technique. Our Fruit code from earlier articles can now be simplified - we no longer need to factor out the base implementation of calcPrice as a method under a different name basePrice. And it still works as intended, here is the updated code:\nimport math # Dollars and Kgs type Dollar* = distinct float Kg* = distinct float proc `$`*(x: Dollar) :string = $x.float proc `==`*(x, y: Dollar) :bool {.borrow.} # Fruit class type Fruit* = ref object of RootObj origin*: string price*: Dollar method `$`*(self: Fruit): string = self.origin \u0026amp; \u0026#34; \u0026#34; \u0026amp; $self.price method reduction(self: Fruit) :Dollar = Dollar(0) method calcPrice*(self: Fruit): Dollar = Dollar(round(self.price.float * 100)/100 - self.reduction().float) # Banana class type Banana* = ref object of Fruit size*: int method reduction(self: Banana): Dollar = Dollar(9) method calcPrice*(self: Banana): Dollar = procCall Fruit(self).calcPrice() # Pumpkin type Pumpkin* = ref object of Fruit weight*: Kg method reduction(self: Pumpkin): Dollar = Dollar(1) method calcPrice*(self: Pumpkin) :Dollar = Dollar(procCall(Fruit(self).calcPrice()).float * self.weight.float) # BigPumpkin type BigPumpkin* = ref object of Pumpkin method calcPrice*(self: BigPumpkin) :Dollar = Dollar(1000) # Construction procs proc newPumpkin*(weight, origin, price): Pumpkin = Pumpkin(weight: weight, origin: origin, price: price) proc newBanana*(size, origin, price): Banana = Banana(size: size, origin: origin, price: price) proc newBigPumpkin*(weight, origin, price): BigPumpkin = BigPumpkin(weight: weight, origin: origin, price: price) As we can see the \u0026ldquo;syntactic style\u0026rdquo; can vary as usual, in line 40 we can use procCall without parenthesis, but on line 51 we need to use it in a \u0026ldquo;calling style\u0026rdquo; in order for precedence to work out.\nSo\u0026hellip; one may wonder, why not just have something like super as in Smalltalk or Java etc? The reason is quite simple, Nim supports multiple dispatch - in other words in Nim we can dispatch based on the types of several of the arguments, as long as they are objects. There is no specific argument in the method call that is privileged as \u0026ldquo;self\u0026rdquo;, we just tend to use the first argument by convention as \u0026ldquo;the receiver\u0026rdquo;. This also means that \u0026ldquo;super\u0026rdquo; has no reasonable meaning in Nim, super of who?\nThe type conversions you would use together with procCall does spell out the \u0026ldquo;super type\u0026rdquo; explicitly (in our example above - \u0026ldquo;Fruit\u0026rdquo;), thus making it very clear which method you want to call. A puritan would possibly claim that it \u0026ldquo;couples\u0026rdquo; the class with its superclass too much (compared to the more abstract uncoupled \u0026ldquo;super\u0026rdquo;). But I think this explicit style fits the Nim mindset better - and even if this makes changing superclasses a bit more tedious (you need to hunt down procCalls and fix the type conversions) - its nothing that some future refactoring tools couldn\u0026rsquo;t easily fix, and changing superclasses isn\u0026rsquo;t what you do every minute anyway.\nOne could also argue that the intention of the programmer is slightly lost with this style. It doesn\u0026rsquo;t obviously read as \u0026ldquo;call the super implementation\u0026rdquo;, and I suspect we may find coders using this also throwing in a small comment stating that hey, this is a super call.\nThe mechanism also enables \u0026ldquo;super super\u0026rdquo; since you can explicitly skip over intermediate classes which of course is generally bad style, but at the same time, explicitness follows the principle of least surprise :)\nCalling overloads on self Link to heading Another scenario we easily could have is a class with several overloads of a method foo in which one or many of them wants to call the \u0026ldquo;primary\u0026rdquo; implementation of the behavior. This is in fact technically the same scenario as the \u0026ldquo;super call\u0026rdquo;, and would be solved the same way - its just an example of multiple dispatch where we are dispatching on more than the first argument. Let\u0026rsquo;s say we have a Foo class which holds a seq of fruit names, for some \u0026hellip; odd reason. And we want to be able to add fruit names to it by sending in various different objects, well, a Fruit obviously, but also collection of Fruits etc.\nimport fruitmethod # Foo class type Foo* = ref object of RootObj fruits*: seq[string] # The core method we want to call method add(self: Foo, fruit: Fruit) = echo \u0026#34; ...and here we actually add it\u0026#34; self.fruits.add($fruit) method add(self: Foo, banana: Banana) = echo \u0026#34;Adding a Banana\u0026#34; procCall self.add(Fruit(banana)) method add(self: Foo, pumpkin: Pumpkin) = echo \u0026#34;Adding a Pumpkin\u0026#34; procCall self.add(Fruit(pumpkin)) method add(self: Foo, fruits: seq[Fruit]) = echo \u0026#34;Adding a bunch of Fruit\u0026#34; for f in fruits: self.add(f) # This is a constructor proc that is normally used to initialize objects proc newFoo(): Foo = result = Foo(fruits: newSeq[string]()) when isMainModule: # Get us a Foo var foo = newFoo() # Add a single Banana foo.add(newBanana(size = 0, origin = \u0026#34;Liberia\u0026#34;, price = 20.Dollar)) # Create a seq of Fruit var s = newSeq[Fruit]() var b = newBanana(size = 0, origin = \u0026#34;Liberia\u0026#34;, price = 20.00222.Dollar) var p = newPumpkin(weight = 5.2.Kg, origin = \u0026#34;Africa\u0026#34;, price = 10.00111.Dollar) s.add(b) s.add(p) # Add them all, this will first call the method for a seq of Fruit, # and that method will in turn call the one for Banana and the one for Pumpkin # and those in turn will use procCall to call the primary method for Fruit. foo.add(s) As we can see above we need to use procCall on line 15 and 19 in order to be able to call the add method that takes a Fruit from the other add methods. So yes, this is not only useful for doing classic super calls.\nConclusion Link to heading The mechanism procCall solves the super call problem with methods, and it also solves similar use cases along the way. As far as I can tell this removes the last \u0026ldquo;hurdle\u0026rdquo; for being able to do serious OO coding in Nim.\nGo Nim!\n"},{"title":"Nim","permalink":"https://goran.krampe.se/2015/03/26/nim-voodoo/","summary":"\u003cp\u003eHaving been a die hard Smalltalker since 1994 I have finally found a new language and community that I am investing myself in. All the Ruby, Python, various JVM languages, C# and Mono etc - none has managed to capture my interest. Ruby and Python always felt like pale shadows of Smalltalk and I really don\u0026rsquo;t want to be tied to the Java eco system, no matter what. And so on and on, lots of languages looking interesting but not being able to withstand my deeper look. As a Smalltalker I probably have acquired a particular taste.\u003c/p\u003e\n\u003cp\u003eSince a few months I am however deeply into Nim. I have written a slew of articles about Nim, and at our company we have decided to bet hard on it. So far I have written a little utility called blimp in Nim, and I have helped creating Urhonimo - the Nim wrapper of the Urho3D game engine.\u003c/p\u003e\n\u003cp\u003eWith a deeper understanding of Nim, although I am far from good at it, what is it that makes me recommend you to try it?\u003c/p\u003e","content":"Having been a die hard Smalltalker since 1994 I have finally found a new language and community that I am investing myself in. All the Ruby, Python, various JVM languages, C# and Mono etc - none has managed to capture my interest. Ruby and Python always felt like pale shadows of Smalltalk and I really don\u0026rsquo;t want to be tied to the Java eco system, no matter what. And so on and on, lots of languages looking interesting but not being able to withstand my deeper look. As a Smalltalker I probably have acquired a particular taste.\nSince a few months I am however deeply into Nim. I have written a slew of articles about Nim, and at our company we have decided to bet hard on it. So far I have written a little utility called blimp in Nim, and I have helped creating Urhonimo - the Nim wrapper of the Urho3D game engine.\nWith a deeper understanding of Nim, although I am far from good at it, what is it that makes me recommend you to try it?\nFundamentals Link to heading For me to really bet on a language, I mean, really investing myself in it, not just dabbling - some things have to be there (in order of importance):\nCross platform and open source Solid story for doing object oriented programming Easy to read and write Powerful abstraction capabilities Turtles Large and small enough community Decent performance Cross platform and open source goes without saying. Nim is MIT licensed and truly grass root open source.\nI want to be able to do OO when it fits, its my preferred way to deal with complex domain models. I am however fairly open to different kinds of OO and my style stems from Smalltalk and not\u0026hellip; factory-abstraction-over-complication-madness like Java people often seem to love. What I have seen so far Nim supports OO quite well.\nEasy to read and write is important, but I am not stuck up on specifics when it comes to syntax, as long as its simple enough. This may also be due to Smalltalk which has a rather unique syntax so I am not afraid to learn something different. Nim\u0026rsquo;s syntax is Pythonical in some aspects and clearly designed to be easy to read and write.\nWith \u0026ldquo;abstraction capabilities\u0026rdquo; I basically mean that the language needs to be sophisticated enough in whichever ways it does that. I want higher level programming, collections, closures, various kinds of polymorphism and so on. The particular style achieving it is secondary, but being able to abstract is paramount. Smalltalk is very capable of abstraction through its pervasive use of closures, objects and dynamic typing. Nim is also very capable but uses closures, objects, methods, generics and compile time macros. A very different mix of mechanisms that in the end reaches the same level of abstraction power.\nSo\u0026hellip; what about \u0026ldquo;Turtles\u0026rdquo;? Some of you probably recognize this and what I refer to is that I want the language to be growable and malleable, thus a big part of the language and of course its libraries, should be implemented in itself. Turtles all the way down. I find this essential, otherwise I will not be able to help evolving the language and its libraries nor will I be able to tailor it to my own needs. A growable language is also important for it to be able to evolve as open source.\nIdeally there should not be a difference between the constructs I create as a developer versus the constructs available to me in the language and base libraries. In other words they should as far as possible be \u0026ldquo;first class\u0026rdquo;. The Nim compiler is written in Nim. The base libraries are written in Nim. Heck, even the garbage collector is written in Nim! Extending the language is easy and there are very few non malleable things.\nI want the community to be large enough to produce an eco system that is useful, but at the same time small enough so that I can actually be an active part of it and make a difference, and be heard! :) This last bit is something most people miss - they just think \u0026ldquo;the bigger the better\u0026rdquo;. Nim is a perfect size for me, the base libraries are ok, the package manager has around 140 packages registered and the community is fairly large with around 130 people on IRC and a lively web forum.\nPerformance is not a crucial factor for me, as long as it beats Ruby/Python I am fine, Smalltalk is normally JITed and typically beats them but doesn\u0026rsquo;t reach C/C++ levels. Nim is on the same level of performance as C/C++.\nThere are probably other languages that satisfies the above fundamentals. :)\nKiller features Link to heading Nim has a few features that together truly makes it shine. Individually they are not unique, there is always some language out there, but the magic arises when they play together:\nMeta programming Deep extensibility Focus on helping the developer The meta programming part is probably the strongest single selling point of Nim. Its Nim\u0026rsquo;s \u0026ldquo;main weapon\u0026rdquo; which it uses for many things.\n\u0026hellip;.examples of macros and templates\u0026hellip;. iterators?\nThe deep extensibility comes in a few mechanisms working together:\nBehaviors are in the form of free procedures The unified calling syntax makes them \u0026ldquo;message like\u0026rdquo; Operators are also procedures There are hooks for []-access, dot-access etc The fact that the behaviors are \u0026ldquo;free procedures\u0026rdquo; (not bound to a class concept) means we can extend types not defined in our own modules, including base types like seq which is the dynamic array workhorse in Nim. For example, in Smalltalk we have collect: which is called map in Nim. In Nim map is actually defined in the system module so its always available.\nBut in Smalltalk we also have collect:with: that does the same but operates on two collections at the same time and expects a closure that instead takes two arguments. Adding it is trivial, 3 lines of code actually, if we skip the comments:\nimport future proc mapWith*[T, W, S](data1: openArray[T], data2: openArray[W], op: proc (x: T, y: W): S {.closure.}): seq[S] = ## Returns a new sequence with the results of `op` applied to every item in ## `data1` and `data2` until either of them runs out. ## ## Since the input is not modified you can use this version of ``map`` to ## transform the type of the elements in the input sequence. Example: ## ## .. code-block:: nim ## let ## a = @[1, 2, 3, 4] ## b = @[\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;, \u0026#34;d\u0026#34;] ## c = map(a, b, proc(x: int, y: string): string = y \u0026amp; $x) ## assert b == @[\u0026#34;1a\u0026#34;, \u0026#34;2b\u0026#34;, \u0026#34;3c\u0026#34;, \u0026#34;4d\u0026#34;] newSeq(result, min(data1.len, data2.len)) for i in 0..result.len-1: result[i] = op(data1[i], data2[i]) when isMainModule: var a = @[1, 2, 3, 4] b = @[\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;, \u0026#34;d\u0026#34;] var c: seq[string] # Using a regular proc c = mapWith(a, b, proc(x: int, y: string): string = y \u0026amp; $x) assert(c == @[\u0026#34;a1\u0026#34;, \u0026#34;b2\u0026#34;, \u0026#34;c3\u0026#34;, \u0026#34;d4\u0026#34;]) # Shorter with lambda syntax, but needs types on params c = mapWith(a, b, (x: int, y: string) =\u0026gt; y \u0026amp; $x) assert(c == @[\u0026#34;a1\u0026#34;, \u0026#34;b2\u0026#34;, \u0026#34;c3\u0026#34;, \u0026#34;d4\u0026#34;]) # It should work if one of the seqs is larger a = @[1, 2, 3, 4, 5, 6] c = mapWith(a, b, (x: int, y: string) =\u0026gt; y \u0026amp; $x) assert(c == @[\u0026#34;a1\u0026#34;, \u0026#34;b2\u0026#34;, \u0026#34;c3\u0026#34;, \u0026#34;d4\u0026#34;]) Above we see that we first import the future module giving us access to the lambda syntax for procs, which is quite elegant. Then we define the new proc called mapWith instead of the regular map. The signature may look a bit complicated, but:\nThe * just marks this procedure to be exported (not needed in this example though) The [T, W, S] are type parameters that will be resolved during compile time at the call site. These type parameters can then be used in the rest of the signature and body of the procedure making this procedure generic for several combinations of types. Then we define three parameters, data1, data2 being the two collections we want to iterate over. Using the special type openarray Nim will allow both arrays (fixed size) and seqs (dynamic size) being passed in. The type parameters T and W here indicate that these collections may have different types for their elements, and we do not specify them here, its for the caller to do so. The op argument is the closure with the signature proc (x: T, y: W): S {.closure.}. This can be read as \u0026ldquo;a procedure taking two arguments x and y of type T and W respectively and returning a result of type S\u0026rdquo;. Its also annotated with a pragma saying that we accept a closure here. Finally the type for the result will be seq[S] which means we will return a seq with elements of type S which thus obviously can be different from both T and W. Then the implementation is very straight forward. We allocate the new seq of correct size (the smallest of the two collections passed in) and then we iterate and run op for each element from the two collections as a pair and collect the result.\nThis is a very nice characteristic when a language is being \u0026ldquo;grown\u0026rdquo; because it means anyone can easily participate in extending the base libraries. The extension can be added and used non intrusively, and then if it turns out to be useful we can share it as a library, and eventually one can also decide to simply merge it into the module that we are extending.\nThe code that comes later is only compiled and executed when we compile this module as a standalone executable. This makes it a nice place to put basic tests. Here we use the simplest possibly style for testing, just doing a series of asserts.\nThe unified calling syntax may seem only like \u0026ldquo;makeup\u0026rdquo; but the fact is that it enables the programmer to more clearly show object oriented intent - that the first argument is responsible for the behavior.\nExamples of the last part is:\nKeeping the standard library pragmatic Automating silly things Approachable base code How to start Link to heading If you do decide to give Nim a spin (and a lot of people do these days), then I can recommend Nim by example and How I start with Nim as good ways to get going.\nThe more detailed path for enlightenment may look like this:\nBrowse Nim-lang.org , and get it . You may also want to get IDE support. Take a look at the Learn section, all my Nim articles can also be reached at the bottom list of article links. Log into #nim channel on freenode, lots of people willing to help! Or use any other means of communicating with the community . What I forgot to shown Link to heading Especially the presentation of Go by Marcus made me often think \u0026ldquo;Oh, shit I forgot to show Y\u0026rdquo;, the stuff I can think of right now are:\nNimsuggest in Aporia Point out the IDE support Some details of the toolset Objects in Nim Size and nature of executables Standard libraries and nimble Noteworthy projects Multiple assignment Typeclasses Concurrency So\u0026hellip; let\u0026rsquo;s go through the above list.\nI missed showing the cross referencing capabilities of Aporia - using nimsuggest (replacing the old nim IDE tools) which is the compiler running in a server mode incrementally parsing Nim code and being able to answer queries like \u0026ldquo;go to definition\u0026rdquo; or do proper completion. The nice part here is of course that its the actual compiler doing it - so it will be correct by definition - and all IDEs can use the same mechanism :)\nI did show Aporia, but there are lots of IDEs with Nim support in various degrees. Sublime, Emacs and Vim all have fairly good support I think. There is also VisualNimrod for VS , but uncertain about its current status.\nNim has a few tools that are important to mention. First of all the nim compiler handles dependencies etc, so no need for Makefiles or the likes. It can also generate documentation in HTML or JSON from the source files which uses the so called \u0026ldquo;doc comments\u0026rdquo; (starting with two ##) that are in reStructeredText format. All documentation is built this way, for example the standard library which is actually not that shabby :). There is a nimfix tool that can help with porting Nim code to the latest compiler, although in beta. There is no formatter or linter yet AFAIK. There is a tool called niminst that produces installers for Nim programs and this is used for the Windows installer etc of Nim itself. The tool called c2nim I did mention and its a very important tool for wrapping external libraries in C or C++.\nObjects in Nim is something I didn\u0026rsquo;t show at all, but I have covered them extensively in my 4 articles on OO in Nim, this is the last one with links to the preceeding . IMHO the capabilities to do OO in Nim are quite nice. Its also worth mentioning that just like Go Nim has no special kind of constructors - and I agree this is a strength. A similar approach is used with exporting newXXX procedures that returns new objects of type XXX, thus encapsulating the implementation details.\nSize and nature of executables? Nim compiles via C/C++ typically and produces small and fast statically linked binaries by default. You can build both static libraries and dynamically linked libraries too, but nim modules are normally handled as source. The examples I showed range from around 60kb for Helloworld, 70kb for sumlines to 95kb for the slightly more complicated example with lambdas etc. Note that by default nim compiles with debug info, so you need to add -d:release option to get these small binaries, otherwise they are slightly larger.\nStandard libraries are included with the compiler download of course, and does cover a fair set of stuff and growing all the time. There is also a neat Nim package tool called Nimble (earlier called Babel) that currently has around 140 packages. No, not close to either Rust or Go, but \u0026hellip; again, not shabby.\nSome noteworthy projects I should have mentioned are Jester , a sinatra like web framework using the new asynchronous networking code and the Nim forum written in Jester using Sqlite. Here is the web forum of Nim .\nSomeone asked about multiple assignment (and I was at a loss of what it meant at the time) and yes, you use the tuple unpacking style as described in the manual in the section on var parameters . But recently Billingsly Wetherfordshire (aka fowl or fowlmouth) showed how you can use Nim macros to support tuple unpacking of arrays too , its a pretty slick example of Nim\u0026rsquo;s power when it comes to extensibility of the language.\nOne area I did mention very briefly but didn\u0026rsquo;t elaborate on is type classes and especially user defined such beasts . There is a good article describing the latter and its IMHO very fascinating stuff, haven\u0026rsquo;t used it yet myself though.\nFinally\u0026hellip; concurrency. Nim has a default model of \u0026ldquo;share nothing\u0026rdquo; threads each with their own heap and GC. Communication is done via channels, but there is also a slew of low level support for shared memory concurrency so\u0026hellip; there is more than one way to do it here .\nConclusion Link to heading Nim is lots of fun and it was a long time ago since I was this impressed by a language not being Smalltalk. :) So hop in and join the fun, I am gokr on #nim/freenode, feel free to ask away.\nHappy hacking!\n"},{"title":"Nim visits GTUG Stockholm","permalink":"https://goran.krampe.se/2015/03/26/nim-visits-gtug/","summary":"\u003cp\u003eYesterday I had the pleasure of presenting the programming language \u003ca href=\"http://nim-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNim\u003c/a\u003e\n at the \u003ca href=\"https://sites.google.com/site/stockholmgtug/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eStockholm GTUG\u003c/a\u003e\n.\nThis evening we were around 50 people, I would guess mainly developers, listening to three presentations:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"http://rust-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eRust\u003c/a\u003e\n, by \u003ca href=\"https://www.linkedin.com/in/johanburell\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eJohan Burell, EVRY\u003c/a\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"http://nim-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNim\u003c/a\u003e\n, by Göran Krampe, 3DICC\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"http://golang,org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eGo\u003c/a\u003e\n, by \u003ca href=\"https://www.linkedin.com/in/marcusolsson1\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eMarcus Olsson, Citerus\u003c/a\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eNow, that\u0026rsquo;s a pretty fitting trio of languages! :) This article is a little followup because I failed to mention so much stuff\u0026hellip;\u003c/p\u003e","content":"Yesterday I had the pleasure of presenting the programming language Nim at the Stockholm GTUG . This evening we were around 50 people, I would guess mainly developers, listening to three presentations:\nRust , by Johan Burell, EVRY Nim , by Göran Krampe, 3DICC Go , by Marcus Olsson, Citerus Now, that\u0026rsquo;s a pretty fitting trio of languages! :) This article is a little followup because I failed to mention so much stuff\u0026hellip;\nRust Link to heading So\u0026hellip; Johan Burell started with presenting Rust . After his presentation I still have the same personal feeling about Rust. I do love the fact that Mozilla is pushing the envelope with a new language. And I can sense their reasoning - they want to crank out maximum performance for a new browser using the future multicore machines people will have, and it must be rock solid. But\u0026hellip; there isn\u0026rsquo;t room for productivity or programming convenience in that vision\u0026hellip;\nAnd that\u0026rsquo;s my main conclusion, its not a language for me because I want a language that makes it fun and easy to program. I don\u0026rsquo;t want to battle a compiler and I like a good garbage collecting system or similar means of freeing me as a developer of arduous tasks. I like exceptions for error handling, well, not as they work in Java, but hey, exceptions work just fine in many other languages.\nJust as most developers I can appreciate the sense of accomplishment when you \u0026ldquo;beat the compiler\u0026rdquo; in these less forgiving languages (think C or C++), but I don\u0026rsquo;t want to work full time in that kind of hurt ;)\nBut thanks Johan for giving a better taste of it, and thanks to the Rust community for pushing forward in the language development arena challenging the behemoths, which of course benefits all new languages and their acceptance - not just Rust.\nGo Link to heading After Johan I presented Nim, but before I get to that I would like to talk about the last presentation - Go by Marcus Olsson.\nMarcus described quite well the reasons and history of Go, and also made his point that the tooling around Go is the primary strength - not the language itself. I haven\u0026rsquo;t been following Go closely but it seems to be gaining lots of traction perhaps as a \u0026ldquo;cleaner no-nonsense\u0026rdquo; alternative to Ruby/Python/Java for writing network server code. At least that\u0026rsquo;s the impression I have, and I wrote more about Go in my article covering languages since 2000 and also in my article about missing Nim .\nFor some criticism check out what what others say. But hey, this is just my personal opinion (and no, I haven\u0026rsquo;t actually used it - but I can already say it wouldn\u0026rsquo;t make a difference) - Go isn\u0026rsquo;t for me, I don\u0026rsquo;t want to sacrifice that amount of capabilities just in order to reach simplicity - languages like Smalltalk (and Lisp etc) has already shown to me that you can have both marvellous capabilities and simplicity, and I would argue Nim is showing the same, albeit in a much different way.\nI do however think there is lots to learn from the community around Go and its toolset and it was fun seeing several of these tools and how they are perceived by a Go developer.\nNim Link to heading I presented Nim, and hopefully it was fun and made some people decide to give it a closer look, which was the idea. It is however very hard to make a language like Nim justice in such a short timeframe, you would typically need 3 hours or similar to be able to give a more complete picture.\nBut if you do decide to give it a spin (and a lot of people do these days), then I can recommend Nim by example and How I start with Nim as good ways to get going.\nThe more detailed path for enlightenment looks like this:\nBrowse Nim-lang.org , and get it . You may also want to get IDE support. Take a look at the Learn section, all my Nim articles can also be reached at the bottom list of article links. Log into #nim channel on freenode, lots of people willing to help! Or use any other means of communicating with the community . What I forgot to show Link to heading Especially the presentation of Go by Marcus made me often think \u0026ldquo;Oh, shit I forgot to show Y\u0026rdquo;, the stuff I can think of right now are:\nNimsuggest in Aporia Point out the IDE support Some details of the toolset Objects in Nim Size and nature of executables Standard libraries and nimble Noteworthy projects Multiple assignment Typeclasses Concurrency So\u0026hellip; let\u0026rsquo;s go through the above list.\nI missed showing the cross referencing capabilities of Aporia - using nimsuggest (replacing the old nim IDE tools) which is the compiler running in a server mode incrementally parsing Nim code and being able to answer queries like \u0026ldquo;go to definition\u0026rdquo; or do proper completion. The nice part here is of course that its the actual compiler doing it - so it will be correct by definition - and all IDEs can use the same mechanism :)\nI did show Aporia, but there are lots of IDEs with Nim support in various degrees. Sublime, Emacs and Vim all have fairly good support I think. There is also VisualNimrod for VS , but uncertain about its current status.\nNim has a few tools that are important to mention. First of all the nim compiler handles dependencies etc, so no need for Makefiles or the likes. It can also generate documentation in HTML or JSON from the source files which uses the so called \u0026ldquo;doc comments\u0026rdquo; (starting with two ##) that are in reStructeredText format. All documentation is built this way, for example the standard library which is actually not that shabby :). There is a nimfix tool that can help with porting Nim code to the latest compiler, although in beta. There is no formatter or linter yet AFAIK. There is a tool called niminst that produces installers for Nim programs and this is used for the Windows installer etc of Nim itself. The tool called c2nim I did mention and its a very important tool for wrapping external libraries in C or C++.\nObjects in Nim is something I didn\u0026rsquo;t show at all, but I have covered them extensively in my 4 articles on OO in Nim, this is the last one with links to the preceeding . IMHO the capabilities to do OO in Nim are quite nice. Its also worth mentioning that just like Go Nim has no special kind of constructors - and I agree this is a strength. A similar approach is used with exporting newXXX procedures that returns new objects of type XXX, thus encapsulating the implementation details.\nSize and nature of executables? Nim compiles via C/C++ typically and produces small and fast statically linked binaries by default. You can build both static libraries and dynamically linked libraries too, but nim modules are normally handled as source. The examples I showed range from around 60kb for Helloworld, 70kb for sumlines to 95kb for the slightly more complicated example with lambdas etc. Note that by default nim compiles with debug info, so you need to add -d:release option to get these small binaries, otherwise they are slightly larger.\nStandard libraries are included with the compiler download of course, and does cover a fair set of stuff and growing all the time. There is also a neat Nim package tool called Nimble (earlier called Babel) that currently has around 140 packages. No, not close to either Rust or Go, but \u0026hellip; again, not shabby.\nSome noteworthy projects I should have mentioned are Jester , a sinatra like web framework using the new asynchronous networking code and the Nim forum written in Jester using Sqlite. Here is the web forum of Nim .\nSomeone asked about multiple assignment (and I was at a loss of what it meant at the time) and yes, you use the tuple unpacking style as described in the manual in the section on var parameters . But recently Billingsly Wetherfordshire (aka fowl or fowlmouth) showed how you can use Nim macros to support tuple unpacking of arrays too , its a pretty slick example of Nim\u0026rsquo;s power when it comes to extensibility of the language.\nOne area I did mention very briefly but didn\u0026rsquo;t elaborate on is type classes and especially user defined such beasts . There is a good article describing the latter and its IMHO very fascinating stuff, haven\u0026rsquo;t used it yet myself though.\nFinally\u0026hellip; concurrency. Nim has a default model of \u0026ldquo;share nothing\u0026rdquo; threads each with their own heap and GC. Communication is done via channels, but there is also a slew of low level support for shared memory concurrency so\u0026hellip; there is more than one way to do it here .\nConclusion Link to heading Nim is lots of fun and it was a long time ago since I was this impressed by a language not being Smalltalk. :) So hop in and join the fun, I am gokr on #nim/freenode, feel free to ask away.\nHappy hacking!\n"},{"title":"Nim seq","permalink":"https://goran.krampe.se/2014/12/03/nim-seq/","summary":"\u003cp\u003eOne of the most important aspects in a language is how powerful and easy it is to use its collection/container types. At least that is my feeling coming from Smalltalk where the Collection classes and their rather rich protocols are used extensively and also cover String and Array and much more. If you peek into the current leading open source Smalltalk - \u003ca href=\"http://pharo.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ePharo\u003c/a\u003e\n - you can see \u003ccode\u003eCollection allSubclasses size\u003c/code\u003e evaluate to \u003cstrong\u003e78\u003c/strong\u003e. Of course, lots of those are special subclasses and not for general use, but fact remains that a strong language \u003cstrong\u003eneeds a strong library of good collections\u003c/strong\u003e.\u003c/p\u003e\n\u003cp\u003eIn Smalltalk I can for example run this:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-smalltalk\" data-lang=\"smalltalk\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"ss\"\u003e#(\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e \u003cspan class=\"m\"\u003e2\u003c/span\u003e \u003cspan class=\"m\"\u003e3\u003c/span\u003e \u003cspan class=\"m\"\u003e4\u003c/span\u003e \u003cspan class=\"m\"\u003e5\u003c/span\u003e\u003cspan class=\"ss\"\u003e)\u003c/span\u003e \u003cspan class=\"nf\"\u003eselect:\u003c/span\u003e [\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"nv\"\u003ex\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"nv\"\u003ex\u003c/span\u003e \u003cspan class=\"nf\"\u003eisOdd\u003c/span\u003e ] \u003cspan class=\"nf\"\u003ethenCollect:\u003c/span\u003e [\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"nv\"\u003ex\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"nv\"\u003ex\u003c/span\u003e \u003cspan class=\"nf\"\u003e*\u003c/span\u003e \u003cspan class=\"m\"\u003e3\u003c/span\u003e ]\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eThis is actually a single method call taking two closures, one to perform a \u0026ldquo;filtering\u0026rdquo;, and one to perform a \u0026ldquo;map\u0026rdquo;. This is not a standard message in \u0026ldquo;good old\u0026rdquo; Smaltalk-80, but it has eventually been added since the usage pattern is so common. To me personally a \u003cstrong\u003emodern language needs similar power\u003c/strong\u003e or I would go nuts. :)\u003c/p\u003e","content":"One of the most important aspects in a language is how powerful and easy it is to use its collection/container types. At least that is my feeling coming from Smalltalk where the Collection classes and their rather rich protocols are used extensively and also cover String and Array and much more. If you peek into the current leading open source Smalltalk - Pharo - you can see Collection allSubclasses size evaluate to 78. Of course, lots of those are special subclasses and not for general use, but fact remains that a strong language needs a strong library of good collections.\nIn Smalltalk I can for example run this:\n#(1 2 3 4 5) select: [:x | x isOdd ] thenCollect: [:x | x * 3 ] This is actually a single method call taking two closures, one to perform a \u0026ldquo;filtering\u0026rdquo;, and one to perform a \u0026ldquo;map\u0026rdquo;. This is not a standard message in \u0026ldquo;good old\u0026rdquo; Smaltalk-80, but it has eventually been added since the usage pattern is so common. To me personally a modern language needs similar power or I would go nuts. :)\nNim has some fundamental Collection types too - and tries deliberately to keep this number small - which I also sympathize with. Nim is meant to be lean and mean, so being minimal in the core is the Right Thing To Do. The ones in the system library are:\narray - Can use any ordinal type as index type, but are fixed size specified at compile time. So fairly restricted use cases I think. set - high performance bit vector, base type can only be ordinals. Again a fairly specialized container, given restriction to ordinals. seq - dynamically resizable array. Index type is integer. I am not listing range, string and cstring types, although especially string/cstring can be viewed as collections, and in Smalltalk they in fact are Collections.\nSo\u0026hellip; in Nim we have seq as the single most important general purpose dynamically sized collection. Now\u0026hellip; this is in the Nim language, if we extend our view to also include the standard library, we find lots more .\nIn order to first learn all you can do with a seq\u0026hellip;. ah. Not so easy it turns out! Nim is not structured with \u0026ldquo;everything you can do with type X here\u0026rdquo;. This fact actually screams for better tooling, but that is another story. One way is basically to search for \u0026ldquo;seq\u0026rdquo; in the documentation of the system module . I did that and also searched through the source :)\nI ended up writing code exploring what I found and more, so put on your Nim glasses, read the code and comments and join the ride. If you want to compile it yourself here is the code , just do \u0026ldquo;nim c seqtest.nim\u0026rdquo; and run it.\nimport fruitbase, future, sequtils, algorithm # Collections are very important in Smalltalk, and they offer a huge protocol # for working with them. The workhorse in Smalltalk is OrderedCollection - which # together with Dictionary probably covers 90% of all collection use. # In Nim the equivalent of an OrderedCollection is the type `seq`. # # This is a little rundown of what you can do with seq using stdlib. # For fun we also add some Smalltalk behaviors, to learn how. # Create an empty collection of Fruit. We can also use: # var s: seq[Fruit] = @[] var s = newSeq[Fruit]() # Some Fruit objects to play with, borrowed from earlier articles on OOP var b = newBanana(size = 0, origin = \u0026#34;Liberia\u0026#34;, price = 20.00222.Dollar) var p = newPumpkin(weight = 5.2.Kg, origin = \u0026#34;Africa\u0026#34;, price = 10.00111.Dollar) # First we have add(), contains() and len() s.add(b) echo(\u0026#34;Seq is \u0026#34; \u0026amp; $s.len \u0026amp; \u0026#34; elements long and contains banana: \u0026#34; \u0026amp; $s.contains(b)) echo(\u0026#34;Seq is \u0026#34; \u0026amp; $s.len \u0026amp; \u0026#34; elements long and contains pumpkin: \u0026#34; \u0026amp; $s.contains(p)) # We can add with `\u0026amp;` too, but it will copy s into a new seq with at least 1 more slot. # This needs discard or assignment since it returns a new seq. # So this is actually concatenation via \u0026#34;copy into a new seq\u0026#34; but for a single element. s = s \u0026amp; p echo(\u0026#34;Seq is \u0026#34; \u0026amp; $s.len \u0026amp; \u0026#34; elements long and contains pumpkin: \u0026#34; \u0026amp; $s.contains(p)) # We can access using [index] and also let the whole seq represent itself as a string, # The implementation of `$` of course calls `$` for the contained elements. echo(\u0026#34;First fruit: \u0026#34; \u0026amp; $s[0]) echo(\u0026#34;The whole seq: \u0026#34; \u0026amp; $s) # Simple iteration, uses the items() iterator under the hood. Iterators are normally inlined # by the compiler and thus cost basically nothing. Calling \u0026#34;items(s)\u0026#34; is not needed, # the for loop will do that automatically and also infer the type of i for us. # Smalltalk: s do: [:i | ... ] for i in s: echo(i.origin) # Insert an element at a given index s.insert(p, 1) # Print countries and index, uses pairs() instead of items() to iterate over both index and value. # Equicalent to Smalltalk: s keysAndValuesDo: [:i :v | ... ] for i,v in pairs(s): echo(\u0026#34;index: \u0026#34; \u0026amp; $i \u0026amp; \u0026#34; country: \u0026#34; \u0026amp; v.origin) # Convert iterator to a seq of key/val tuples, just stumbled over it. # Like calling Dictionary\u0026gt;\u0026gt;associations in Smalltalk, but here its # generalized for any kind of iterator. echo(toSeq(pairs(s))) # It should produce a copy, so should hold true assert(toSeq(items(s)) == s) # Print in string form, neat for debugging. echo(\u0026#34;repr:\u0026#34; \u0026amp; repr(s)) # Delete at index. Here is a little issue with system.nim and sequtils.nim overlapping slightly. # Should be fixed. The following will not compile since its ambiguous: # s.delete(0) # Instead we need to explicitly call it in the system module. system.delete(s, 0) # Get and remove last element. echo s.pop echo(\u0026#34;The whole seq: \u0026#34; \u0026amp; $s) echo(\u0026#34;Seq is \u0026#34; \u0026amp; $s.len \u0026amp; \u0026#34; elements long and contains banana: \u0026#34; \u0026amp; $s.contains(b)) # Concatenate two seqs copying into a new longer seq. Like in \u0026#34;,\u0026#34; in Smalltalk. s = s \u0026amp; s echo(\u0026#34;After concat seq is \u0026#34; \u0026amp; $s.len) # Throw in a banana again for tests below s.add(b) # Sort using proc syntax s.sort(proc(x, y: Fruit) :int = cmp(x.origin, y.origin)) # Sort using do syntax s.sort do (x, y: Fruit) -\u0026gt; int: cmp(x.origin, y.origin) # Sort using new lambda syntax s.sort((x, y: Fruit) =\u0026gt; cmp(x.origin, y.origin)) # NOTE: In the following three calls to map we needed to wrap with $(...) to avoid # an internal error in Compiler for Nim 0.10.1. # # Smalltalk\u0026#39;s #collect: is Nim\u0026#39;s `map`, here using proc syntax. # In Smalltalk: s collect: [:x | x origin ] echo($(s.map(proc(x:Fruit): string = x.origin))) # ...and future lambda syntax, basically as short and clean as Smalltalk! echo($(s.map((x:Fruit) =\u0026gt; x.origin))) # ...or using mapIt template variant, but needs a type arg for the new seq echo($(s.mapIt(string, it.origin))) # Smalltalk\u0026#39;s #select: is Nim\u0026#39;s `filter`, here using proc syntax. # In Smalltalk: s select: [:x | x origin = \u0026#39;Liberia\u0026#39; ] echo(s.filter(proc(x:Fruit): bool = x.origin == \u0026#34;Liberia\u0026#34;)) # ...and future lambda syntax, almost as short and clean as Smalltalk! echo(s.filter((x:Fruit) =\u0026gt; (x.origin == \u0026#34;Liberia\u0026#34;))) # ...and filterIt template variant, muahaa, shorter than Smalltalk! echo(s.filterIt(it.origin == \u0026#34;Liberia\u0026#34;)) # But Smalltalk has a HUGE amount of more behaviors like: # detect:ifNone:, allSatisfy:, anySatisfy:, reject:, inject:into: # ...well, there are TONS we would like :) # # Here is allSatisfy: and anySatisfy:, easily implemented. proc allSatisfy*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool = ## Returns true if all the items fulfill the predicate. ## ## Example: ## ## .. code-block:: ## let numbers = @[10, 20, 30] ## assert numbers.allSatisfy(proc(x: int): bool = x \u0026gt; 5) result = true for i in seq1: if not pred(i): return false proc anySatisfy*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool = ## Returns true if any of the items fulfill the predicate. ## ## Example: ## ## .. code-block:: ## let numbers = @[10, 20, 30] ## assert numbers.anySatisfy(proc(x: int): bool = x \u0026gt; 25) result = false for i in seq1: if pred(i): return true let numbers = @[10, 20, 30] assert(numbers.allSatisfy(proc(x: int): bool = x \u0026gt; 5)) assert(numbers.anySatisfy(proc(x: int): bool = x \u0026gt; 25)) echo($s \u0026amp; \u0026#34; all come from Africa: \u0026#34; \u0026amp; $s.allSatisfy((x:Fruit) =\u0026gt; (x.origin == \u0026#34;Africa\u0026#34;))) # We can also check if s isNil echo(s.isNil) s = nil echo(s.isNil) # Let\u0026#39;s see what happens if we try to port a few random Smalltalk snippets I wrote # down just perusing the Smalltalk protocol for OrderedCollection: # #(1 2 3 4 5) select: [:x | x odd ] thenCollect: [:x | x * 3 ] # Above we do a filter on an array of Numbers getting those that are odd # and then we map them by multiplying with 3. # We need odd, an immediate template should inline it I think. # SomeInteger is a type class matching all integer types in Nim. template odd(x: SomeInteger): bool {.immediate.} = (x and 1) == 1 # And then we can write it like this using the lambda macro. # For filter we don\u0026#39;t need to declare type for x, but for map we do. # I suspect this is because we start out with a literal from which # type is inferenced one level. var q = @[1,2,3,4,5].filter((x) =\u0026gt; x.odd).map((x:int) =\u0026gt; x * 3) echo(q) # Or procs style, slightly longer and also needing return type of procs. # Here we get away without declaring x:int, turning the code into generic procs. # Andreas would call it \u0026#34;bad style\u0026#34; I think. q = @[1,2,3,4,5].filter(proc(x): bool = x.odd).map(proc(x): int = x * 3) echo(q) # #(1 2 3 4) sum # Sum is already defined in math module from math import sum echo(@[1,2,3,4,5].sum) # #(one two three two four) copyWithoutAll: #(one two) # The above creates a new collection without any ones or twos. # One and two are symbols (canonical strings) # We need copyWithoutAll:, let\u0026#39;s call it filterWithout. # In Nim we don\u0026#39;t need \u0026#34;All\u0026#34; to imply that the argument # should be a collection, we can overload for other types. # accumulateResult is a template taking an iterator. # sequtils both has a filter iterator and a filter proc, here # we use the iterator. This means both the accumulation and the iteration # will be inlined. I think :) # # `notin` is a template which is sugar for `not seq2.contains(x)` # It is also marked as a keyword so `x.notin(seq2)` does not compile, it needs # to be `x notin seq2` proc filterWithout*[T](seq1, seq2: seq[T]): seq[T] = accumulateResult(filter(seq1, proc(x:T):bool = x notin seq2)) var qq = @[\u0026#34;one\u0026#34;, \u0026#34;two\u0026#34;, \u0026#34;three\u0026#34;, \u0026#34;two\u0026#34;, \u0026#34;four\u0026#34;].filterWithout(@[\u0026#34;one\u0026#34;, \u0026#34;two\u0026#34;]) echo($qq) # #(1 2 3 4) includesAny: #(1 2) # #(1 2 3 4) includesAll: #(1 2) # Both the above can be added easily similar to allSatisfy, anySatisfy: proc containsAny*[T](seq1, seq2: seq[T]): bool = ## Returns true if any of the items in seq2 is in seq1. ## ## Example: ## ## .. code-block:: ## let numbers = @[10, 20, 30] ## assert numbers.containsAny(@[5, 10]) result = false for i in seq2: if i in seq1: return true proc containsAll*[T](seq1, seq2: seq[T]): bool = ## Returns true if all of the items in seq2 are in seq1. ## ## Example: ## ## .. code-block:: ## let numbers = @[10, 20, 30] ## assert numbers.containsAll(@[10, 20]) result = true for i in seq2: if i notin seq1: return false assert(@[1,2,3,4].containsAll(@[1,2])) assert(@[1,2,3,4].containsAny(@[1,2,20])) Conclusion Link to heading The seq type has a reasonable minimal set of behavior, but we should add more into sequtils IMHO. Make it really strong, really smart and convenient. This is extremely important for developer productivity. I can gladly sit down and look through the Smalltalk Collection hierarchy to find more behavior we could implement.\nHappy hacking!\n"},{"title":"Nim and OO, Part IV","permalink":"https://goran.krampe.se/2014/11/30/nim-and-oo-part-iv/","summary":"\u003cp\u003eAs I described in \u003ca href=\"/2014/10/29/nim-and-oo\" \u003ethe\u003c/a\u003e\n \u003ca href=\"/2014/10/31/nim-and-oo-part-ii\" \u003eearlier\u003c/a\u003e\n \u003ca href=\"/2014/10/31/nim-and-oo-part-iii\" \u003eposts\u003c/a\u003e\n Nim didn\u0026rsquo;t support \u0026ldquo;super calls\u0026rdquo; when using \u003cstrong\u003emethods\u003c/strong\u003e instead of statically bound \u003cstrong\u003eprocs and generics\u003c/strong\u003e. My article caused a little bit of discussion around this on IRC and Andreas decided to implement the mechanism he already had planned - but had not fully decided a good name for.\u003c/p\u003e\n\u003cp\u003eThe other day this mechanism \u003ca href=\"https://github.com/Araq/Nimrod/commit/105a0616a9da7c9c85adfa488a1db42eb17daafb\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eentered the devel branch\u003c/a\u003e\n which means it will be official in the next release of Nim, which I suspect will be out before the end of 2014. It should be noted that devel is mainly undergoing bug fixing, so unless you are paranoid it\u0026rsquo;s pretty usable. Now\u0026hellip; of course I had to try out super calls in my sample code\u0026hellip;\u003c/p\u003e","content":"As I described in the earlier posts Nim didn\u0026rsquo;t support \u0026ldquo;super calls\u0026rdquo; when using methods instead of statically bound procs and generics. My article caused a little bit of discussion around this on IRC and Andreas decided to implement the mechanism he already had planned - but had not fully decided a good name for.\nThe other day this mechanism entered the devel branch which means it will be official in the next release of Nim, which I suspect will be out before the end of 2014. It should be noted that devel is mainly undergoing bug fixing, so unless you are paranoid it\u0026rsquo;s pretty usable. Now\u0026hellip; of course I had to try out super calls in my sample code\u0026hellip;\nInstead of calling it static_call - implying that the call resolution is made at compile time statically, the name ended up as procCall - implying the call resolution is simply done just like its done for procs. Same, same - different words. To put it another way, even though we are calling a method, let the static types of the arguments decide which method to call, not the actual runtime types.\nA bit of repetition from the earlier articles - today you can select among overloaded procs to call by using type conversion, so if you want to call myProc that takes an argument of type A when you have an object of type B in your hand (B being a sub type of A), you just do myProc(A(b)).\nThis is called a type conversion and can be viewed as a type safe cast, it only works if its safe to do it. Nim also has cast but generally its something you should only use if you know what the heck you are doing. :)\nNow\u0026hellip; methods don\u0026rsquo;t rely on static typing - they resolve based on the actual runtime type of the objects - that\u0026rsquo;s their whole reason for existing and this is essential in supporting more complex OO code. So the type conversion technique in itself only works for selecting among overloaded procs, not methods.\nBut now, with the addition of procCall we can call overloaded methods using the exact same technique. Our Fruit code from earlier articles can now be simplified - we no longer need to factor out the base implementation of calcPrice as a method under a different name basePrice. And it still works as intended, here is the updated code:\nimport math # Dollars and Kgs type Dollar* = distinct float Kg* = distinct float proc `$`*(x: Dollar) :string = $x.float proc `==`*(x, y: Dollar) :bool {.borrow.} # Fruit class type Fruit* = ref object of RootObj origin*: string price*: Dollar method `$`*(self: Fruit): string = self.origin \u0026amp; \u0026#34; \u0026#34; \u0026amp; $self.price method reduction(self: Fruit) :Dollar = Dollar(0) method calcPrice*(self: Fruit): Dollar = Dollar(round(self.price.float * 100)/100 - self.reduction().float) # Banana class type Banana* = ref object of Fruit size*: int method reduction(self: Banana): Dollar = Dollar(9) method calcPrice*(self: Banana): Dollar = procCall Fruit(self).calcPrice() # Pumpkin type Pumpkin* = ref object of Fruit weight*: Kg method reduction(self: Pumpkin): Dollar = Dollar(1) method calcPrice*(self: Pumpkin) :Dollar = Dollar(procCall(Fruit(self).calcPrice()).float * self.weight.float) # BigPumpkin type BigPumpkin* = ref object of Pumpkin method calcPrice*(self: BigPumpkin) :Dollar = Dollar(1000) # Construction procs proc newPumpkin*(weight, origin, price): Pumpkin = Pumpkin(weight: weight, origin: origin, price: price) proc newBanana*(size, origin, price): Banana = Banana(size: size, origin: origin, price: price) proc newBigPumpkin*(weight, origin, price): BigPumpkin = BigPumpkin(weight: weight, origin: origin, price: price) As we can see the \u0026ldquo;syntactic style\u0026rdquo; can vary as usual, in line 40 we can use procCall without parenthesis, but on line 51 we need to use it in a \u0026ldquo;calling style\u0026rdquo; in order for precedence to work out.\nSo\u0026hellip; one may wonder, why not just have something like super as in Smalltalk or Java etc? The reason is quite simple, Nim supports multiple dispatch - in other words in Nim we can dispatch based on the types of several of the arguments, as long as they are objects. There is no specific argument in the method call that is privileged as \u0026ldquo;self\u0026rdquo;, we just tend to use the first argument by convention as \u0026ldquo;the receiver\u0026rdquo;. This also means that \u0026ldquo;super\u0026rdquo; has no reasonable meaning in Nim, super of who?\nThe type conversions you would use together with procCall does spell out the \u0026ldquo;super type\u0026rdquo; explicitly (in our example above - \u0026ldquo;Fruit\u0026rdquo;), thus making it very clear which method you want to call. A puritan would possibly claim that it \u0026ldquo;couples\u0026rdquo; the class with its superclass too much (compared to the more abstract uncoupled \u0026ldquo;super\u0026rdquo;). But I think this explicit style fits the Nim mindset better - and even if this makes changing superclasses a bit more tedious (you need to hunt down procCalls and fix the type conversions) - its nothing that some future refactoring tools couldn\u0026rsquo;t easily fix, and changing superclasses isn\u0026rsquo;t what you do every minute anyway.\nOne could also argue that the intention of the programmer is slightly lost with this style. It doesn\u0026rsquo;t obviously read as \u0026ldquo;call the super implementation\u0026rdquo;, and I suspect we may find coders using this also throwing in a small comment stating that hey, this is a super call.\nThe mechanism also enables \u0026ldquo;super super\u0026rdquo; since you can explicitly skip over intermediate classes which of course is generally bad style, but at the same time, explicitness follows the principle of least surprise :)\nCalling overloads on self Link to heading Another scenario we easily could have is a class with several overloads of a method foo in which one or many of them wants to call the \u0026ldquo;primary\u0026rdquo; implementation of the behavior. This is in fact technically the same scenario as the \u0026ldquo;super call\u0026rdquo;, and would be solved the same way - its just an example of multiple dispatch where we are dispatching on more than the first argument. Let\u0026rsquo;s say we have a Foo class which holds a seq of fruit names, for some \u0026hellip; odd reason. And we want to be able to add fruit names to it by sending in various different objects, well, a Fruit obviously, but also collection of Fruits etc.\nimport fruitmethod # Foo class type Foo* = ref object of RootObj fruits*: seq[string] # The core method we want to call method add(self: Foo, fruit: Fruit) = echo \u0026#34; ...and here we actually add it\u0026#34; self.fruits.add($fruit) method add(self: Foo, banana: Banana) = echo \u0026#34;Adding a Banana\u0026#34; procCall self.add(Fruit(banana)) method add(self: Foo, pumpkin: Pumpkin) = echo \u0026#34;Adding a Pumpkin\u0026#34; procCall self.add(Fruit(pumpkin)) method add(self: Foo, fruits: seq[Fruit]) = echo \u0026#34;Adding a bunch of Fruit\u0026#34; for f in fruits: self.add(f) # This is a constructor proc that is normally used to initialize objects proc newFoo(): Foo = result = Foo(fruits: newSeq[string]()) when isMainModule: # Get us a Foo var foo = newFoo() # Add a single Banana foo.add(newBanana(size = 0, origin = \u0026#34;Liberia\u0026#34;, price = 20.Dollar)) # Create a seq of Fruit var s = newSeq[Fruit]() var b = newBanana(size = 0, origin = \u0026#34;Liberia\u0026#34;, price = 20.00222.Dollar) var p = newPumpkin(weight = 5.2.Kg, origin = \u0026#34;Africa\u0026#34;, price = 10.00111.Dollar) s.add(b) s.add(p) # Add them all, this will first call the method for a seq of Fruit, # and that method will in turn call the one for Banana and the one for Pumpkin # and those in turn will use procCall to call the primary method for Fruit. foo.add(s) As we can see above we need to use procCall on line 15 and 19 in order to be able to call the add method that takes a Fruit from the other add methods. So yes, this is not only useful for doing classic super calls.\nConclusion Link to heading The mechanism procCall solves the super call problem with methods, and it also solves similar use cases along the way. As far as I can tell this removes the last \u0026ldquo;hurdle\u0026rdquo; for being able to do serious OO coding in Nim.\nGo Nim!\n"},{"title":"Squeak to Nim, come in Nim...","permalink":"https://goran.krampe.se/2014/11/03/squeak-to-nim/","summary":"\u003cp\u003eIn my exploration of \u003ca href=\"http://nim-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNim\u003c/a\u003e\n the turn has come to see how we can use Nim together with \u003ca href=\"http://squeak.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSqueak\u003c/a\u003e\n.\u003c/p\u003e\n\u003cp\u003eSqueak (and Pharo) has two basic mechanisms of interfacing with the C world:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"http://stephane.ducasse.free.fr/FreeBooks/CollectiveNBlueBook/greenberg.pdf\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSqueak VM plugins\u003c/a\u003e\n. That pdf is old, but still fairly accurate I guess.\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"http://wiki.squeak.org/squeak/1414\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSqueak FFI\u003c/a\u003e\n, Foreign Function Interface.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe VM plugins are basically a controlled way to introduce new \u0026ldquo;named\u0026rdquo; primitives in Smalltalk that can be invoked from Smalltalk. A plugin can be built either linked into the VM binary (statically) or as a dynamically loaded library (dll, so, dylib etc). When \u0026ldquo;all else fails\u0026rdquo; a plugin is the way to go, but they are a bit awkward to work with.\u003c/p\u003e\n\u003cp\u003eThen we have the FFI which is a generic way to dynamically call dynamically loaded libraries. In other words, no compilation step needed - just type the correct Smalltalk line and the library will load and the calls work. Now\u0026hellip; sure, the FFI mechanism is a bit slower, since it needs to look at arguments and make the proper type conversions for the call. But the FFI is heavily used in the commercial Terf system, in fact, all the OpenGL calls are done through it. So its quite proven, and not that slow.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eNOTE:\u003c/strong\u003e There are in fact several FFIs today, the old one, the one called Alien and Pharo is brewing a new one called UFFI.\u003c/p\u003e\n\u003cp\u003eLet\u0026rsquo;s see if we can use the good old FFI with Nim.\u003c/p\u003e","content":"In my exploration of Nim the turn has come to see how we can use Nim together with Squeak .\nSqueak (and Pharo) has two basic mechanisms of interfacing with the C world:\nSqueak VM plugins . That pdf is old, but still fairly accurate I guess. Squeak FFI , Foreign Function Interface. The VM plugins are basically a controlled way to introduce new \u0026ldquo;named\u0026rdquo; primitives in Smalltalk that can be invoked from Smalltalk. A plugin can be built either linked into the VM binary (statically) or as a dynamically loaded library (dll, so, dylib etc). When \u0026ldquo;all else fails\u0026rdquo; a plugin is the way to go, but they are a bit awkward to work with.\nThen we have the FFI which is a generic way to dynamically call dynamically loaded libraries. In other words, no compilation step needed - just type the correct Smalltalk line and the library will load and the calls work. Now\u0026hellip; sure, the FFI mechanism is a bit slower, since it needs to look at arguments and make the proper type conversions for the call. But the FFI is heavily used in the commercial Terf system, in fact, all the OpenGL calls are done through it. So its quite proven, and not that slow.\nNOTE: There are in fact several FFIs today, the old one, the one called Alien and Pharo is brewing a new one called UFFI.\nLet\u0026rsquo;s see if we can use the good old FFI with Nim.\nMaking a Nim library Link to heading It turns out that making a library isn\u0026rsquo;t hard, but there are a few things of note. An oh, all files here if you want to try it out. Ok, so here is our testlib.nim library:\n# We exercise some trivial types and how they map. # # SqueakFFI Nim # ========= ====== # long =\u0026gt; int # char* =\u0026gt; cstring import math # A single proc, returns an int. Since we are on 32 bits # an int is 4 bytes (same size as pointer) and in Squeak FFI # this is a long. The exportc pragma ensures that the exported # name for this proc is exactly \u0026#34;hello\u0026#34; and not mangled. proc hello*(): int {.exportc.} = 42 # Trivial, a Nim string can be sent as a cstring because they are # automatically 0-terminated. proc foo*(): cstring {.exportc.} = \u0026#34;hey\u0026#34; # Not a problem taking int arguments, they are \u0026#34;long\u0026#34; in Squeak FFI. proc add*(x, y:int): int {.exportc.} = x + y # Just return the length of a cstring proc length*(x: cstring): int {.exportc.} = len(x) # Here we convert cstrings to Nim strings, concatenate and return. proc concat*(x, y: cstring): cstring {.exportc.} = $x \u0026amp; $y The only thing above that wasn\u0026rsquo;t obvious - ehrm, unless you read the manual of course - is that you need to use the exportc pragma to make the symbols stay unmangled in the library.\nTo compile the above to a 32 bit .so library on Linux, we create a corresponding config file called testlib.nim.cfg:\n--app:lib --cpu:i386 --passC:\u0026#34;-m32\u0026#34; --passL:\u0026#34;-m32\u0026#34; The above are options to the nim compiler, so we could have just used them on the command line. Now we compile it with nim c testlib and it should produce a file called libtestlib.so.\nThe first options means \u0026ldquo;compile a lib instead of a program\u0026rdquo;, and the second means \u0026ldquo;make it 32 bit\u0026rdquo;. The last two were needed to make it boil down to the C compiler, might be a bug somewhere, but it works.\nNow\u0026hellip; the above library worked just fine to call from Squeak\u0026hellip; at least all procs except the concat proc. Boom. And it almost DROVE ME NUTS trying to figure out why I was having issues sending char* arguments from Squeak. I thought the problem was on the Squeak side, and I must say that googling for info on stuff like this is a bit of a haystack operation.\nSidenote: Squeak does suffer quite hard from a lack of proper singular documentation. I mean, lots of docs, wiki etc, all over - but what is current? What works? Its a bit of a problem in the Squeak community I would say. And\u0026hellip; well, is Pharo different? Not entirely sure. I really like Smalltalk, Squeak and Pharo, and I am used to this, but I must say its a mess.\nIt turns out that the concat proc is the only one that creates a Nim string, that code needs the GC, and the GC\u0026hellip; is in the nimrtl.nim module. This is also documented, but its in the Compiler manual . So it wasn\u0026rsquo;t hard, we just need to make sure to build it too as 32 bits, and copy it to some reasonable place:\nnim c --cpu:i386 --passC:\u0026#34;-m32\u0026#34; --passL:\u0026#34;-m32\u0026#34; --app:lib --define:createNimRtl lib/nimrtl.nim sudo cp lib/libnimrtl.so /lib/i386-linux-gnu/ Then\u0026hellip; we also need to add an option to compiling our lib, -d:useNimRtl, so testlib.nim.cfg looks like this:\n--app:lib --cpu:i386 --passC:\u0026#34;-m32\u0026#34; --passL:\u0026#34;-m32\u0026#34; -d:useNimRtl The end result is that we now have a dynamically loadable runtime library libnimrtl.so that has the GC etc. The above option makes sure our libtestlib.so uses that runtime library which in turn makes Nim strings work fine and tada, concat() works.\nSmalltalk side Link to heading Okidoki, so\u0026hellip; thanks Andreas for helping me to get it working. Now, time to play. I put the libtestlib.so in the directory where I run Squeak. Now\u0026hellip; I am working with an old Squeak, but it also works just fine with Pharo 3.0 . So easiest way to see it in action is to download Pharo 3.0 and try it there:\nDownload Pharo 3.0 , unzip somewhere. Unzip this file into the pharo3.0 directory. It has the libtestlib.so and also the Smalltalk source. Install FFI into Pharo: I did it by opening the Configuration browser, finding FFI configuration, then \u0026ldquo;Install stable version\u0026rdquo;. The FFI plugin itself is included in the VM. File in the Smalltalk source: Open a File browser, select the file Nim-Test.st and do \u0026ldquo;Install into new changeset\u0026rdquo;. Open a Test Runner, search for \u0026ldquo;Nim\u0026rdquo; using upper left field, then run the test FFINimTest. If its green - yiha! You find the calls on the class side of FFINimTestLibrary. For example the one for concat():\nffiConcat: a with: b \u0026#34;self ffiConcat: \u0026#39;a\u0026#39; with: \u0026#39;b\u0026#39; \u0026#34; \u0026lt;cdecl: char* \u0026#39;concat\u0026#39; (char* char*) module: \u0026#39;testlib\u0026#39;\u0026gt; ^self externalCallFailed You can select the code between \u0026quot;\u0026quot; and run it with \u0026ldquo;inspect it\u0026rdquo;. Hopefully you get the Smalltalk String 'ab'.\nRemark Link to heading First versions of this article mentioned segfaults, but after looking closer it seems those segfaults appeared due to me using Smalltalk unloadModule: 'testlib' and then trying again, thus causing a reload. Apparently there is a problem doing this in the VM. But the code seems solid, I have run it hours on end with no problems.\nI also studied the Squeak FFI code a bit up close and yes, for char* arguments it will copy them out into temporary allocated memory, and then make the call. Afterwards it will deallocate them before returning back into Squeak. For a char* result it will instantiate a ByteString object from inside the plugin and copy the bytes over into it, so the actual pointer and memory returned from Nim, is not used. If we use byte* we can do the same operation from inside Squeak, as the Terf codebase does extensively. But both approaches seem to be solid.\nAs noted the pointer returned from Nim in concat() is the pointer to the Nim string itself. This works because Nim strings \u0026ldquo;double\u0026rdquo; as cstring, because they are null terminated. That string is however a GC tracked ref in Nim, so Nim will eventually garbage collect it - but the GC doesn\u0026rsquo;t run in its own thread, so the data is safe for Squeak to copy - at least until we return back to Nim in the next call. But generally having Nim return pointers to GC tracked data, is of course not safe unless Squeak immediately copies it. Now\u0026hellip; thankfully for char* Squeak FFI does it automatically, for other types we can do it manually in Smalltalk code.\nConclusion Link to heading The old Squeak FFI is quite proven and works. As we saw Nim can produce libraries quite easily. And using Nim instead of C/C++ is a nobrainer to me. :)\nHappy hacking!\n"},{"title":"Nim and OO, Part II","permalink":"https://goran.krampe.se/2014/10/31/nim-and-oo-part-ii/","summary":"\u003cp\u003eIn the \u003ca href=\"/2014/10/29/nim-and-oo\" \u003eprevious article\u003c/a\u003e\n when I explored OO mechanisms in \u003ca href=\"http://nim-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNim\u003c/a\u003e\n I felt I dropped the ball a bit in my Fruit example. This is a followup.\u003c/p\u003e\n\u003cp\u003eIn that article we first implemented some Fruit \u0026ldquo;classes\u0026rdquo; mixing methods and procs. Then I presented a cleaned up version using methods only, and a teeny template in order to reuse a base method. This template was needed since Nim currently doesn\u0026rsquo;t have a \u0026ldquo;call-next-method-matching\u0026rdquo; for multimethods like Dylan or CLOS have. This is being discussed and I think all agree that there needs to be \u003cstrong\u003esome\u003c/strong\u003e mechanism so that you can call a \u0026ldquo;next lesser match\u0026rdquo; of all matching multimethods.\u003c/p\u003e\n\u003cp\u003eBut I also wrote that the example \u003cstrong\u003ecan be written perfectly well using generics and procs only\u003c/strong\u003e, thus ensuring static binding and maximum speed. But the \u0026ldquo;super call\u0026rdquo; problem also existed for procs, and the template hack was just a hack. After more experimentation I now \u003cstrong\u003ethink I found the proper Nim way\u003c/strong\u003e to do this so let\u0026rsquo;s take a look\u0026hellip;\u003c/p\u003e","content":"In the previous article when I explored OO mechanisms in Nim I felt I dropped the ball a bit in my Fruit example. This is a followup.\nIn that article we first implemented some Fruit \u0026ldquo;classes\u0026rdquo; mixing methods and procs. Then I presented a cleaned up version using methods only, and a teeny template in order to reuse a base method. This template was needed since Nim currently doesn\u0026rsquo;t have a \u0026ldquo;call-next-method-matching\u0026rdquo; for multimethods like Dylan or CLOS have. This is being discussed and I think all agree that there needs to be some mechanism so that you can call a \u0026ldquo;next lesser match\u0026rdquo; of all matching multimethods.\nBut I also wrote that the example can be written perfectly well using generics and procs only, thus ensuring static binding and maximum speed. But the \u0026ldquo;super call\u0026rdquo; problem also existed for procs, and the template hack was just a hack. After more experimentation I now think I found the proper Nim way to do this so let\u0026rsquo;s take a look\u0026hellip;\nGenerics Link to heading In Nim we can use generics to \u0026ldquo;generate\u0026rdquo; multiple \u0026ldquo;instances\u0026rdquo; of procs, for all different combinations of static types being used to call this proc. To be precise, the compiler doesn\u0026rsquo;t necessarily need to generate multiple copies, it can deal with it using a simple case switch on types, or whatever - but its a reasonable mental model of what happens. Another mental model is that a generic proc, as long as your shit compiles, will be run with the types of the arguments at the given callsite. :)\nSo if we have a proc declared as proc calcPrice(self): Dollar with no type specified for self then Nim will consider that to be the same as proc calcPrice[T](self: T): Dollar and collect all callsites and for each unique static type of self being passed in, it will generate a matching calcPrice proc. Presumably writing all these procs manually would result in equivalent code.\nThis is how my final fairly nice generic variant of the Fruit library looks like:\nimport math # Dollars and Kgs type Dollar* = distinct float Kg* = distinct float proc `$`*(x: Dollar) :string = $x.float proc `==`*(x, y: Dollar) :bool {.borrow.} # Fruit class, all procs for Fruit are generic type Fruit* = ref object of RootObj origin*: string price*: Dollar # Default reduction is 0 proc reduction*(self) :Dollar = Dollar(0) # This one factored out from calcPrice below # so that subclasses can \u0026#34;super\u0026#34; call it. proc basePrice*(self): Dollar = Dollar(round(self.price.float * 100)/100 - self.reduction().float) # Default implementation, if you don\u0026#39;t override. proc calcPrice*(self) :Dollar = self.basePrice() # Banana class, relies on inherited calcPrice() type Banana* = ref object of Fruit size*: int # Overrides reduction though. proc reduction*(self: Banana): Dollar = Dollar(9) # Pumpkin, overrides calcPrice() and makes a \u0026#34;super call\u0026#34; by calling basePrice() type Pumpkin* = ref object of Fruit weight*: Kg # Also overrides reduction. proc reduction*(self: Pumpkin): Dollar = Dollar(1) # Override to multiply super implementation by weight. # Calling basePrice works because it will not lose type of self so # when basePrice() calls self.reduction() it will resolve properly. proc calcPrice*(self: Pumpkin) :Dollar = Dollar(self.basePrice().float * self.weight.float) # BigPumpkin, overrides calcPrice() without super call # No override of reduction. type BigPumpkin* = ref object of Pumpkin method calcPrice*(self: BigPumpkin) :Dollar = Dollar(1000) # Construction procs, this encapsulates our structure of the objects in this module. proc newPumpkin*(weight, origin, price): Pumpkin = Pumpkin(weight: weight, origin: origin, price: price) proc newBanana*(size, origin, price): Banana = Banana(size: size, origin: origin, price: price) proc newBigPumpkin*(weight, origin, price): BigPumpkin = BigPumpkin(weight: weight, origin: origin, price: price) Okidoki. Before I came up with the above code which looks quite simple - I experimented with a composition style using delegation instead of inheritance, and used generics too. It did work, but it got quite messy. The above solution on the other hand feels like a simple pattern one can use to solve this \u0026ldquo;super call\u0026rdquo; issue. Now\u0026hellip; what was the problem again? :)\nProblem: When you only use procs and overload them to give implementations of calcPrice() for Banana, Pumpkin and BigPumpkin - and also a base default implementation in the base class Fruit - then you can\u0026rsquo;t call the one in Fruit from any of the others. In other words, you can\u0026rsquo;t make a \u0026ldquo;super call\u0026rdquo;, just try it and watch the infinite recursion!\nWe could in theory use the type Fruit for self in the base implementation (and not a generic self), and use a type conversion of self like Fruit(self).calcPrice() to be able to call it - but then you will be running the calcPrice() in Fruit with self as being a Fruit! And that\u0026rsquo;s no good, because when it subsequently calls self.reduction() it will not resolve to the proper proc, it will only resolve to the base implementation in Fruit. So forget using abstract types as types for the self argument in base implementations of procs, it is a BAD idea.\nSolution: We can factor out the base implementation of calcPrice() under another name, like basePrice(). Then we can easily call it from the subclasses. And the default implementation of calcPrice() in Fruit will just call basePrice(). And this is important: we use generic self for the proc arguments in the Fruit class, so that we don\u0026rsquo;t lose type information when we call those procs.\nAnd here is the test code to see it works as it should:\nimport fruit # Create some objects using proper encapsulated construction procs var p = newPumpkin(weight = 5.2.Kg, origin = \u0026#34;Africa\u0026#34;, price = 10.00111.Dollar) var b = newBanana(size = 0, origin = \u0026#34;Liberia\u0026#34;, price = 20.00222.Dollar) var bp = newBigPumpkin(weight = 15.Kg, origin = \u0026#34;Africa\u0026#34;, price = 10.Dollar) # Check correct pricing assert(b.calcPrice() == 11.0.Dollar) assert(p.calcPrice() == (9*5.2).Dollar) assert(bp.calcPrice() == 1000.Dollar) proc testing(x) :Dollar = result = x.calcPrice() echo($result) # Check correct pricing when called via a proc with generic type assert(testing(b) == 11.Dollar) assert(testing(p) == (9*5.2).Dollar) assert(testing(bp) == 1000.Dollar) echo \u0026#34;All good.\u0026#34; Conclusion Link to heading How to use generics in Nim for someone like me who haven\u0026rsquo;t used generics in a loooong time, is a bit of a head twister. But after a few hours of messing, it starts to click.\nThe only \u0026ldquo;issue\u0026rdquo; above I guess - is the fact that the default calcPrice() makes an extra call to basePrice() (but only the default, so only for Bananas) so a few cycles lost there unless Nim optimizes it away. Something that a template probably could solve of course. :)\n"},{"title":"Nim and OO, Part III","permalink":"https://goran.krampe.se/2014/10/31/nim-and-oo-part-iii/","summary":"\u003cp\u003eSo previously in \u003ca href=\"/2014/10/31/nim-and-oo-part-ii\" \u003eNim and OO Part II\u003c/a\u003e\n we saw how we could solve the \u0026ldquo;super call\u0026rdquo; issue using only procs and generics in \u003ca href=\"http://nim-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNim\u003c/a\u003e\n. This means that all code is statically bound.\u003c/p\u003e\n\u003cp\u003eBut if you have read all these article you know I also tried the more appropriate mechanism for OO - so called \u003cstrong\u003emethods\u003c/strong\u003e. In Nim a proc is a regular statically bound function, simple and fast. A \u003cstrong\u003emethod\u003c/strong\u003e on the other hand uses dynamic multimethod dispatch on the \u003cstrong\u003eruntime types\u003c/strong\u003e of all object parameters. The easy way to do objects in Nim (with inheritance of behavior) is using methods - but of course, this means dynamic lookup that has a runtime cost, but quite small as we will see.\u003c/p\u003e\n\u003cp\u003eTime for benchmarking!\u003c/p\u003e","content":"So previously in Nim and OO Part II we saw how we could solve the \u0026ldquo;super call\u0026rdquo; issue using only procs and generics in Nim . This means that all code is statically bound.\nBut if you have read all these article you know I also tried the more appropriate mechanism for OO - so called methods. In Nim a proc is a regular statically bound function, simple and fast. A method on the other hand uses dynamic multimethod dispatch on the runtime types of all object parameters. The easy way to do objects in Nim (with inheritance of behavior) is using methods - but of course, this means dynamic lookup that has a runtime cost, but quite small as we will see.\nTime for benchmarking!\nWith methods the fruit code looks like this:\nimport math # Dollars and Kgs type Dollar* = distinct float Kg* = distinct float proc `$`*(x: Dollar) :string = $x.float proc `==`*(x, y: Dollar) :bool {.borrow.} # Fruit class type Fruit* = ref object of RootObj origin*: string price*: Dollar method reduction(self: Fruit) :Dollar = Dollar(0) # Code broken out enabling super call of it method basePrice(self: Fruit): Dollar = Dollar(round(self.price.float * 100)/100 - self.reduction().float) method calcPrice*(self: Fruit): Dollar = self.basePrice() # Banana class type Banana* = ref object of Fruit size*: int method reduction(self: Banana): Dollar = Dollar(9) method calcPrice*(self: Banana): Dollar = self.basePrice() # Pumpkin type Pumpkin* = ref object of Fruit weight*: Kg method reduction(self: Pumpkin): Dollar = Dollar(1) method calcPrice*(self: Pumpkin) :Dollar = Dollar(self.basePrice().float * self.weight.float) # BigPumpkin type BigPumpkin* = ref object of Pumpkin method calcPrice*(self: BigPumpkin) :Dollar = Dollar(1000) # Construction procs proc newPumpkin*(weight, origin, price): Pumpkin = Pumpkin(weight: weight, origin: origin, price: price) proc newBanana*(size, origin, price): Banana = Banana(size: size, origin: origin, price: price) proc newBigPumpkin*(weight, origin, price): BigPumpkin = BigPumpkin(weight: weight, origin: origin, price: price) The same code below using only procs and generics. This time I have also used proper fn[T](self: T) instead of the fn(self) - Andreas felt it looked \u0026ldquo;sloppy\u0026rdquo; without the proper signatures :). So again:\nimport math # Dollars and Kgs type Dollar* = distinct float Kg* = distinct float proc `$`*(x: Dollar) :string = $x.float proc `==`*(x, y: Dollar) :bool {.borrow.} # Fruit class, procs are generic type Fruit* = ref object of RootObj origin*: string price*: Dollar # Default reduction is 0 proc reduction*[T](self: T) :Dollar = Dollar(0) # This one factored out from calcPrice # so that subclasses can \u0026#34;super\u0026#34; call it. proc basePrice[T](self: T): Dollar = Dollar(round(self.price.float * 100)/100 - self.reduction().float) # Default implementation, if you don\u0026#39;t override. proc calcPrice*[T](self: T) :Dollar = self.basePrice() # Banana class, relies on inherited calcPrice() type Banana* = ref object of Fruit size*: int proc reduction*(self: Banana): Dollar = Dollar(9) # Pumpkin, overrides calcPrice() and calls basePrice() type Pumpkin* = ref object of Fruit weight*: Kg proc reduction*(self: Pumpkin): Dollar = Dollar(1) # Override to multiply super implementation by weight. # Calling basePrice works because it will not lose type of self so # when it calls self.reduction() it will resolve properly. proc calcPrice*(self: Pumpkin) :Dollar = Dollar(self.basePrice().float * self.weight.float) # BigPumpkin, overrides calcPrice() without super call # No reduction. type BigPumpkin* = ref object of Pumpkin proc calcPrice*(self: BigPumpkin) :Dollar = Dollar(1000) # Construction procs proc newPumpkin*(weight, origin, price): Pumpkin = Pumpkin(weight: weight, origin: origin, price: price) proc newBanana*(size, origin, price): Banana = Banana(size: size, origin: origin, price: price) proc newBigPumpkin*(weight, origin, price): BigPumpkin = BigPumpkin(weight: weight, origin: origin, price: price) Now\u0026hellip; the same technique is used to solve the \u0026ldquo;super call\u0026rdquo; problem: Just factor out the code under a different method/proc name that you can call from the subclasses. If you are hell bent on using only procs - then the generics are important in that factored out method, otherwise subsequent calls to self will not resolve \u0026ldquo;properly\u0026rdquo;.\nDiscussing this today with Andreas he made a good point - you can use procs for private behaviors, and methods for public ones.\nIts easier to get procs to bind statically properly for private behaviors. Because then you know all the callsites, they are in this module. So in this example, you can easily make basePrice() a proc since its private. The public protocol is better to keep as methods, since we don\u0026rsquo;t have control over those callsites and the types of the variables being passed. And as you will see later in this article, it will become apparent immediately.\nAndreas and static_call to the rescue Link to heading The technique with factoring out to enable \u0026ldquo;super calls\u0026rdquo; will not be needed in the future. Andreas aims to add the so called static_call mechanism that you can use to \u0026ldquo;select\u0026rdquo; which method you wish to call.\nUPDATE: See (part IV)[2014/11/30/nim-and-oo-part-iv] about this.\nToday you can select any proc by using type conversion, so if you want to call the myProc that takes an A when you have a b: B in your hand, you just do myProc(A(b)). But methods don\u0026rsquo;t rely on static typing - they resolve based on the runtime type of the objects, so this technique currently only works for selecting among overloaded procs, not methods.\nThe idea is that using static_call myMethod(A(b)) in front of the method call will cause Nim to use the static types of the callsite to resolve the proper method instead of the runtime types. So the name static implies static resolution instead of dynamic which is how methods usually do it.\nThis static_call makes it very clear what method you are calling and IMHO this indeed sounds much more explicit than the \u0026ldquo;call the next method\u0026rdquo;-approach that many other languages (CLOS, Dylan, Julia) seem to use. I guess those other languages strive to not \u0026ldquo;hard wire\u0026rdquo; the selection to specific types, thus preserving the \u0026ldquo;super style\u0026rdquo; that adapts to inheritance refactorings, but\u0026hellip; it still seems a bit too automagic-gotcha-there-buddy.\nPerformance Link to heading I devised a silly benchmark creating 5 million of each Bananas, Pumpkins and BigPumpkins in a single seq[Fruit], and also 5 million of each in separate seq typed for each kind. And then looping over these collections and calculating the total price, and doing it 10 times over just to get more proper numbers.\nIf you have a heterogenous collection with proc based objects - then you need to do \u0026ldquo;manual type testing\u0026rdquo; code using of in order to know what to call:\n# Loop over fruits, darnit! Need to do type check and conversion for f in fruits: if f of Banana: total += Banana(f).calcPrice.float # Note that you need to check for BigPumpkin first! `of` is true for all subtypes. elif f of BigPumpkin: total += BigPumpkin(f).calcPrice.float elif f of Pumpkin: total += Pumpkin(f).calcPrice.float \u0026hellip;which you don\u0026rsquo;t need to do if you have the methods based objects of course. Speed? It turns out the manual checking above is around 10% slower than the automatic resolution done by Nim when you use methods. Neat.\nBut the penalty for methods can be seen for the homogenous collections - those loops run about 2x faster for procs with static binding. A factor of two sounds big, but in fact - that\u0026rsquo;s a very impressively small number I think! For pure static code the compiler can do lots of funky optimizations\nBelow is the code used for benching the methods based code, the code for procs/generis is just the same but with the above test-type-and-convert code added in the fruits loop:\nimport fruitmethod, math, future # Create LOTS of fruit in a heterogenous seq, sum up their costs. # Also create three separate seqs, and sum up, to be fair comparing with procs. # Util to measure time import times, os template time(s: stmt): expr = let t0 = cpuTime() s cpuTime() - t0 # A heterogenous seq collection typed as Fruit var fruits = newSeq[Fruit]() # And some homogenous var bananas = newSeq[Banana]() var pumpkins = newSeq[Pumpkin]() var bigPumpkins = newSeq[BigPumpkin]() # Fill em up for i in 1..5000000: fruits.add(newBanana(size = 0, origin = \u0026#34;Liberia\u0026#34;, price = 20.00222.Dollar)) fruits.add(newPumpkin(weight = 5.2.Kg, origin = \u0026#34;Africa\u0026#34;, price = 10.00111.Dollar)) fruits.add(newBigPumpkin(weight = 15.Kg, origin = \u0026#34;Africa\u0026#34;, price = 10.Dollar)) bananas.add(newBanana(size = 0, origin = \u0026#34;Liberia\u0026#34;, price = 20.00222.Dollar)) pumpkins.add(newPumpkin(weight = 5.2.Kg, origin = \u0026#34;Africa\u0026#34;, price = 10.00111.Dollar)) bigPumpkins.add(newBigPumpkin(weight = 15.Kg, origin = \u0026#34;Africa\u0026#34;, price = 10.Dollar)) var total: float = 0 proc calcTenTimes() = for i in 1..10: # Loop over fruits, our classes use methods so we do not need to cast # f from Fruit to specific types. for f in fruits: total += f.calcPrice.float proc calcTenTimesSame() = for i in 1..10: total = 0 for f in bananas: total += f.calcPrice.float for f in pumpkins: total += f.calcPrice.float for f in bigPumpkins: total += f.calcPrice.float echo \u0026#34;Time for calc: \u0026#34; \u0026amp; $time(calcTenTimes()) echo \u0026#34;Time for calc same: \u0026#34; \u0026amp; $time(calcTenTimesSame()) Running it:\ntime ./shopmethod Time for calc: 1.591322 Time for calc same: 3.068159000000001 real\t0m8.342s user\t0m7.163s sys\t0m1.106s Conclusion Link to heading First of all, damn Nim is fast! Creating 30 million objects, in a few collections dynamically growing. Then looping 10 times over them calling calcPrice() about 300 million times? And it all takes about 8 seconds? I am impressed.\nSecondly, the penalty for methods is in fact very small - but if you happen to have code that indeed does millions of calls in a tight loop - sure, procs will be faster of course. But my guess is that for the majority of real code - the difference will not even be noticed.\nAndreas also told me that method lookup is indeed pretty optimized, and can be faster than in C++ even. So I will use methods with my objects, especially for the public behaviors - and just be happy.\nFinally, why are methods not used in the stdlibs? Quoting Andreas: \u0026ldquo;The major reason why we don\u0026rsquo;t use methods in the stdlib is that they don\u0026rsquo;t play well with the effect system and our dead code elimination optimization.\u0026rdquo;\nOf course. Remember, Nim is meant to be usable for system level programming. So having the stdlibs be \u0026ldquo;fully static\u0026rdquo; in nature is important.\nGo Nim!\n"},{"title":"Ubuntu Just Works","permalink":"https://goran.krampe.se/2014/10/30/ubuntu-just-works/","summary":"\u003cp\u003eA friend of mine is having a less optimal experience with Linux, and I realized I could jot down my experience for the last few years.\u003c/p\u003e\n\u003cp\u003eI have been using Linux on my desktop for a long time now, about 10 years I think. Early I played \u0026ldquo;distro jumping\u0026rdquo; and used \u003ca href=\"http://www.lunar-linux.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eLunar Linux\u003c/a\u003e\n for quite some time on my older Zepto laptop.\u003c/p\u003e\n\u003cp\u003eBut at some point I just decided that, nah, source distros are huge time sinks. Not necessarily because they have issues, but because they are fun to tinker with. I also felt it was \u0026ldquo;smarter\u0026rdquo; to know a mainstream Linux well, so I decided to go for \u0026ldquo;least friction\u0026rdquo;, and moved to Ubuntu. When Unity hit I did contemplate using something else, at least an alternative shell, but decided to just \u0026ldquo;hang in there\u0026rdquo;, and now I tend to like it. Recently I upgraded to \u003ca href=\"http://www.ubuntu.com/desktop/developers\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eUbuntu 14.04 LTS\u003c/a\u003e\n, it was pretty eventless.\u003c/p\u003e","content":"A friend of mine is having a less optimal experience with Linux, and I realized I could jot down my experience for the last few years.\nI have been using Linux on my desktop for a long time now, about 10 years I think. Early I played \u0026ldquo;distro jumping\u0026rdquo; and used Lunar Linux for quite some time on my older Zepto laptop.\nBut at some point I just decided that, nah, source distros are huge time sinks. Not necessarily because they have issues, but because they are fun to tinker with. I also felt it was \u0026ldquo;smarter\u0026rdquo; to know a mainstream Linux well, so I decided to go for \u0026ldquo;least friction\u0026rdquo;, and moved to Ubuntu. When Unity hit I did contemplate using something else, at least an alternative shell, but decided to just \u0026ldquo;hang in there\u0026rdquo;, and now I tend to like it. Recently I upgraded to Ubuntu 14.04 LTS , it was pretty eventless.\nMy main laptop is a Lenovo X220 with a Samsung 840 Pro SSD disk. Its easily the best laptop I have ever had and runs Linux extremely well, and it has a REAL DAMN KEYBOARD.\nSleeping works, just close the lid and open it to wake up. External screen works perfectly, I have an external monitor in addition to the laptop with a shared desktop - just plug in (or out) the cord and Ubuntu detects and adjusts. Just move windows between them and so on. And the little function keys for screen brightness, the little LED light, sound volume buttons etc - all seem to work fine.\nStuff I use all the time:\nChrome and Firefox for browsing. Sometimes one works better than the other. Thunderbird for email. Sometimes goes busy, busy on the CPU, but otherwise copes fine with my three accounts, 10 mailinglists and about 70000 emails? Or more perhaps. Gedit for text editing, its simple and works fairly nicely. I am not an Emacs/Vim guy. Shotwell for handling photos. It imports easily from phones too, including iPhone (doing it as I write this actually). Skype and Pidgin for chatting. Pidgin tends to bomb out when waking up from sleep, but otherwise works fine. Gimp for image editing. LibreOffice for those kind of documents. Evince or Acrobat Reader for pdfs. Evince is often better. Tons of terminal windows, I should learn to use tabs in the terminal though. Gnome Screenshot for taking (duh) screenshots and SimpleScreenRecorder for making screen capture videos. VirtualBox running Windows XP, various Linuxes etc. Even accelerated 3D works in XP. VLC or Totem for watching movies, both work very well. Transmission for bittorrents. Remmina for VNC/RDP sessions to other machines. OpenShot for editing videos, mostly my daughter\u0026rsquo;s figure skating competitions :) Pharo and Squeak for Smalltalk development. ack-grep , nano \u0026amp; apt-show-versions :) Now, its true that I am a fairly experienced Linux user by now, but I really do feel \u0026ldquo;shit just works\u0026rdquo; these days.\nHappy hacking!\n"},{"title":"Nim and OO","permalink":"https://goran.krampe.se/2014/10/29/nim-and-oo/","summary":"\u003cp\u003e\u003ca href=\"http://nim-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNim\u003c/a\u003e\n is presented as an \u003cstrong\u003eimperative\u003c/strong\u003e language. And yes, it has some of its roots in the Pascal line of languages, but it also has a set of powerful abstraction mechanisms making it very suitable for object oriented programming. And when I write \u003cem\u003e\u0026ldquo;object oriented\u0026rdquo;\u003c/em\u003e I am referring to a broader flexible sense of OO in which objects can be formulated with attached behavior, polymorphism between different objects, some kind of reuse model of code (inheritance etc) and some type of dynamic dispatch.\u003c/p\u003e\n\u003cp\u003eSince I am a \u003ca href=\"http://www.squeak.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003elong time\u003c/a\u003e\n \u003ca href=\"http://pharo.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSmalltalker\u003c/a\u003e\n that is my main reference for \u003cem\u003e\u0026ldquo;good OO\u0026rdquo;\u003c/em\u003e and not the \u0026hellip; monstrous OO often seen in Java or C++. Its hard to explain the differences, but let me just say that OO in Smalltalk is elegant and natural, very much like in Ruby or Python - but ever so more streamlined. Smalltalk is a dynamically strongly typed reflective language with a heavily closure based style.\u003c/p\u003e\n\u003cp\u003eIn this article I will try to make \u0026ldquo;sense\u0026rdquo; out of how to do OO in Nim.\u003c/p\u003e","content":"Nim is presented as an imperative language. And yes, it has some of its roots in the Pascal line of languages, but it also has a set of powerful abstraction mechanisms making it very suitable for object oriented programming. And when I write \u0026ldquo;object oriented\u0026rdquo; I am referring to a broader flexible sense of OO in which objects can be formulated with attached behavior, polymorphism between different objects, some kind of reuse model of code (inheritance etc) and some type of dynamic dispatch.\nSince I am a long time Smalltalker that is my main reference for \u0026ldquo;good OO\u0026rdquo; and not the \u0026hellip; monstrous OO often seen in Java or C++. Its hard to explain the differences, but let me just say that OO in Smalltalk is elegant and natural, very much like in Ruby or Python - but ever so more streamlined. Smalltalk is a dynamically strongly typed reflective language with a heavily closure based style.\nIn this article I will try to make \u0026ldquo;sense\u0026rdquo; out of how to do OO in Nim.\nOO in Smalltalk Link to heading We roughly have the following mechanisms in Smalltalk related to OO, and the first 4 are the same as in Java:\nSingle inheritance class model. Normal \"receiver only\" dynamic dispatch. Able to do super and self calls. Garbage collection. In addition Smalltalk adds very important salt and pepper, which Java definitely doesn't have:\nEverything is an object including all datatypes, so we can inherit from them and also extend/override with methods. Every behavior is a message invoking a method, including all operators. Only exceptions are assignment and return. Dynamic duck typing. Pervasive use of closures with support of non local return enabling expressive protocols. Then of course Smalltalk goes \"OO Banzai!\" with:\nClasses are objects too, so they have methods and inheritance and a class... Class variables and class instance variables. Full meta level meaning your code can modify itself 100% during runtime. And... yes, there is more to Smalltalk - but I think the above captures most big parts of what other developers would call the OO mechanisms in the **language**. Then there is more in the libraries and tools of course, like for example the excellent Collection classes. For doing reasonable OO the Banzai stuff is not needed, its however what enables Smalltalk to be a fully reflective IDE in itself. Bullets 5-9 are also not essential to reasonable OO, but they are what makes Smalltalk transcend languages like Java, so in that sense its interesting to see what Nim offers in the similar space.\nSo ideally I want to see Nim support at least 1-4 and hopefully also cover 5-8 but using other mechanisms, given that Nim is a totally different beast.\nHow does Nim stack up? Link to heading Learning Nim is really fun, its like a \u0026ldquo;box of chocolate\u0026rdquo; with lots of slick mechanisms to learn. This also makes it slightly confusing - what stuff should I use regularly? What should I avoid? What parts combine to enable OO in Nim? Its not clear :)\nAnd this walk through is also not entirely clear, but its a series of experiments with concluding remarks referring back to the Smalltalk laundry list above. Could I restructure this article? Probably. Did I use too much sample code? Probably. Is the article too long? No doubt.\nBut here we go\u0026hellip;\nProcs Link to heading We can start with the work horse in Nim - procs . A proc is simply a regular statically typed function. This means we have static compile time binding for them - and they support \u0026ldquo;overloading\u0026rdquo; on the arguments, so we can define many procs with different implementations for different types on the arguments.\nAlso, Nim introduced so called UFCS before D established that acronym, so syntactically these calls are equivalent:\nfn(a, b) a.fn(b) Having both proc overloading and the Uniform Function Call Syntax in combination with the neat modules system where one module can define procs using types from other modules (pretty obvious you can do that) - then we already can do \u0026ldquo;OO looking code\u0026rdquo; in a simpler fashion. For example we can easily add a reversed() method to the type string that returns a new string with characters reversed.\nFirst, lets just verify that string doesn\u0026rsquo;t already have it. I use Aporia and I have turned on \u0026ldquo;Enable suggest feature\u0026rdquo; in Preferences, then it tries to help me:\n\u0026hellip;so nothing there right now. Let\u0026rsquo;s hack. In the beginning below we see that reversed() already exists for openarray, which means both array and seq types. Then we add it for string:\n# Some data to play with var anArray = [1, 2, 3, 4] var aSequence = @[\u0026#34;a\u0026#34;, \u0026#34;b\u0026#34;, \u0026#34;c\u0026#34;] # Aha, in module algorithm.nim we already have reversed() for openarray # which is the type covering both array and seq. # Hehe, we can import down here too if we like import algorithm # And yes, reversed works for those guys echo(anArray.reversed()) echo(aSequence.reversed()) # But it doesn\u0026#39;t work for string, let\u0026#39;s add it proc reversed(s: string) :string = ## Shamefully ripped from algorithm.nim for openarrays result = s var x = 0 var y = s.high while x \u0026lt; y: swap(result[x], result[y]) dec(y) inc(x) # Testing it, works for literals echo \u0026#34;abc\u0026#34;.reversed # Works for vars too of course :) var test = \u0026#34;Goran\u0026#34; echo(test) echo(test.reversed) # And yes, not destructive. \u0026#34;reverse\u0026#34; (no d) would be destructive. echo(test) \u0026hellip;using Aporia we can actually immediately see right after we wrote that proc, that the compiler picked it up and offered it as a suggestion when we started typing in test code:\nCompile and run:\ngokr@yoda:~$ nim c -r --verbosity:0 testreversed.nim @[4, 3, 2, 1] @[c, b, a] cba Goran naroG Goran gokr@yoda:~$ Funny sidenote: \u0026ldquo;Göran\u0026rdquo; didn\u0026rsquo;t work so well\u0026hellip; UTF8 strikes! But this is fully natural given our non-UTF8 aware implementation, we end up reversing the two UTF8 bytes representing \u0026ldquo;ö\u0026rdquo;\u0026hellip;\nRemark Link to heading In each \u0026ldquo;Remark\u0026rdquo; heading I try to connect back to Smalltalk and that laundry list. Most Smalltalk implementations have some mechanism for \u0026ldquo;class extensions\u0026rdquo; (able to add methods in classes outside your package) and they are quite easy in Nim, even for builtin datatypes, since both procs (and methods, continue reading) are defined separately and operate on types, not \u0026ldquo;just\u0026rdquo; objects. And we have the UFCS syntactic sugaring, making the illusion complete.\nIn Nim most operators are handled the same way, so we can implement things that are \u0026ldquo;hard wired\u0026rdquo; in other languages, like == (equality) using the same mechanism. This nicely reverbs with Smalltalk.\nI would say that 5 and 6 on that list have fair support in Nim.\nDistinct types Link to heading One extra twist regarding the fundamental datatypes in Nim is that we can do type aliases and distinct types of them. An alias is just that - same, same. But a distinct type creates a completely separate type - it just happens to \u0026ldquo;be\u0026rdquo; the same thing. This makes the builtin datatypes a bit more malleable and also enables our code to be very typesafe and strict.\nPlay time, just messing a bit:\n# We create a FreakInt which behaves like an int, but is its own type. # We can not pass a FreakInt when someone wants an int - and vice versa. # This also means that all operators and procs defined for ints, do NOT # apply for a FreakInt - they are dumb as hell basically. type FreakInt = distinct int # Ok, so we borrow multiplication by an int proc `*` (x: FreakInt, y: int): FreakInt {.borrow.} # Let\u0026#39;s override `+`: FreakInt also multiplies by 2... proc `+` (x, y: FreakInt): FreakInt = FreakInt((int(x) + int(y)) * 2) # Can we go down the rabbit hole? What happens with a distinct # type of a distinct type? type UltraFreak = distinct FreakInt # Ok, so we borrow `*` and `+` from FreakInt? # No, it turns out it borrows from the base type int - this is NOT inheritance. proc `+` (x, y: UltraFreak): UltraFreak {.borrow.} proc `*` (x: UltraFreak, y: int): UltraFreak {.borrow.} # UltraFreak ints multiply by 10 when doing subtraction... proc `-` (x, y: UltraFreak): UltraFreak = UltraFreak((int(x) - int(y)) * 10) # Hold onto hat.. var i: int = 5 f: FreakInt = 6.FreakInt # Conversion, same as FreakInt(6) u: UltraFreak = 7.UltraFreak # Did FreakInt manage to borrow `*` from int? yes assert(int(f * i) == 30) # Did FreakInt manage to override `+`? yes assert(int(f + f) == 24) # Did UltraFreak manage to borrow `+` from... what? # Ok, from int, not FreakInt! assert(int(u + u) == 14) # Also from int, not FreakInt! assert(int(u * i) == 35) # But we did get our own `-`, right? Yes we did. assert(int(u - 3.UltraFreak) == 40) Remark Link to heading It seems to me that distinct types in Nim captures even more of 5 and 6 - while we can\u0026rsquo;t inherit from fundamental datatypes, we can in fact:\nCreate distinct types from them and extend those. And actually even borrow base type implementations on a proc-by-proc or op-by-op basis. But ONLY from the base type. I guess this also works for other base types than the builtins. There is quite a lot of other mechanisms that I will not cover here, like overriding \u0026ldquo;.\u0026quot;-access or the dereferencing operator \u0026ldquo;[]\u0026rdquo; and so on. I would say all of this is enough in order to be able to work with fundamental types in \u0026ldquo;an object oriented manner\u0026rdquo; similar to how we can do it in Smalltalk.\nTuples Link to heading Ok, let\u0026rsquo;s move to more complex data. A tuple is like a struct in C or a \u0026ldquo;record\u0026rdquo; or a \u0026ldquo;row\u0026rdquo; in a database table. Its a composition of named and typed fields in a specific order:\ntype Person: tuple[name: string, age: int] So its the simplest heterogenous composition of data in Nim, there is no overhead at all and they do not know their type at runtime (so dynamic dispatch on tuples is not possible) and there is no hiding of members either.\nThus a tuple is a very basic type, and given their limitations compared to their Bigger Brother the object, they should be used when convenience and/or zero overhead matters more than information hiding or complex attached behavior.\nIn the Nim standard library we find tuples as the smaller building blocks inside Collection types like KeyValuePair, a Complex number, a Point or a Rectangle in graphics, or a Name \u0026amp; Version combination etc. Small and simple things, and when it comes to Collections the fact that they carry zero storage overhead is of course important. But they are not used even nearly as much as objects are, some quick searches like grep -r \u0026quot;= tuple\u0026quot; in lib shows 25 hits, objects are used typically 10x more, and I probably listed half of the tuple uses in the first sentence of this paragraph :)\nIf you are unsure if you should use a tuple or an object, I suspect you are better off with an object.\nRemark Link to heading Tuples are seemingly most interesting internally in Collections or similar lower level code. For most OO code objects are to be preferred.\nRef and ptr Link to heading Before we go further we need to look at ref and ptr in Nim. Nim can work closer to the metal than say Java or Smalltalk. To be able to do that, Nim needs regular C style pointers, they are declared as ptr Sometype. Such a pointer variable, that directly points to a memory location, is normally used when interfacing with C or when you want to play slightly \u0026ldquo;outside the box\u0026rdquo;, for example if you wish to allocate something in memory and pass it over to another thread - keeping track yourself when to deallocate.\nAs a language that wants to cover all bases this is essential stuff to have, and of course - this is unsafe territory, feel free to shoot yourself in your proverbial foot. But for regular \u0026ldquo;application level\u0026rdquo; code we probably do not need to use ptrat all.\nInstead we use ref which is in fact also a pointer, but its a friendlier one that does a bit of automatic allocation and especially deallocation for us using the garbage collector. If we declare type KeyValuePair = tuple[key: string, value: string] without using ref - and then use that to declare a variable x in a proc, then that variable will be allocated in the stack frame when the proc is called, and thus also disappear when the proc returns. Its fairly logical - var x is a tuple, not a pointer to one. Nothing is in this case allocated on the heap and no garbage collection is needed, since the whole value was inside the stack frame.\nBut for making data that lives longer than the current invocation of a proc, we tend to use \u0026ldquo;ref\u0026rdquo; types. For such types the value will be allocated on the heap, and the variable will hold a pointer to it, and the garbage collector tracks our references.\nA bit of training code showing that while we normally use ref to refer to objects, we can refer to other types like enums as well:\n# Playing with ref, enum and assignment type LightImpl = enum LiGreen, LiYellow, LiRed Light = ref LightImpl # Convenience method, good style proc newLight(): Light = new(result) var # This is a variable allocated in the stackframe light: LightImpl # This allocates and initializes a LightImpl on the heap # and makes lightHolder refer to it. If you do initialization # separately you can also use `new(lightHolder)` lightHolder = new(LightImpl) # Better style to call a proc to do it. lightHolder2 = newLight() # Dereference to get the Light value, check it has the default value assert(lightHolder[] == LiGreen) # Set the local stackframe allocated Light to a different value light = LiYellow # Assignment copies the bits of light to the Light on the heap # You need to use `[]` dereferencing here. lightHolder[] = light # Should be yellow now assert(lightHolder[] == LiYellow) # Let\u0026#39;s modify the local stackframe light light = LiRed # Make sure the Light on the heap is still yellow assert(lightHolder[] == LiYellow) Remark Link to heading Since I have been working primarily in Java, C# and Smalltalk the last 20 years (ouch) I have gotten used to variables almost always being references to objects, and objects almost always being allocated on the heap. Nim has value types , and then ref and ptr is used to create reference types pointing at them. I am not a language designer though - perhaps one can express it using more precise words.\nProc variables are automatically allocated in the stack frame, as usual. This is also true of ref variables, but for those we only allocate the actual pointer bits there. But where does it point? This is where an allocation step comes into play - using new(). Calling new() with a ref variable as argument, will allocate the type that the ref variable refers to on the heap, and then set our ref variable to point there. Obviously you can also explicitly pass the type that the ref refers to (in the example code LightImpl) but that makes the code more brittle and less encapsulated.\nI think the greater flexibility of Nim, where we can choose to allocate values or references to values has benefits in more complex scenarios - and definitely for performance. It seems fairly well \u0026ldquo;embedded\u0026rdquo; in nice mechanisms so that general application level OO code doesn\u0026rsquo;t suffer too much from this \u0026ldquo;complication\u0026rdquo;.\nObjects Link to heading Ah, finally! But this is not your dad\u0026rsquo;s Java objects, or your granddad\u0026rsquo;s Smalltalk objects. First of all, we don\u0026rsquo;t have \u0026ldquo;classes\u0026rdquo; - in Nim that term is not really used. Instead we talk about an object type.\nAn object is similar to a tuple, but it knows its type at runtime and we can decide which members we want to be visible outside the containing module. We can also inherit from an existing object type, single inheritance. Let\u0026rsquo;s hack some code:\n# Distinct types seem useful for units, not essential # for this sample code, but whatever, let\u0026#39;s use them. type Dollar* = distinct float Kg* = distinct float # We can define $ for Dollars too proc `$`*(x: Dollar) :string = $x.float # Let\u0026#39;s borrow `==` for simpler code proc `==`*(x, y: Dollar) :bool {.borrow.} # Let\u0026#39;s create a base class for fruits with country # of origin and a price in dollar. Note that we typically # inherit from RootObj which is basically like the Object # class in both Smalltalk and Java. # Also note that we declare Fruit to be a ref type. type Fruit* = ref object of RootObj origin*: string price*: Dollar # We like to deal with different sizes of bananas # so we create a subtype and add a size member. type Banana* = ref object of Fruit size*: int # And pumpkins can have very different weights type Pumpkin* = ref object of Fruit weight*: Kg # A very big one BigPumpkin* = ref object of Pumpkin # And... can we also make a non ref subtype of # a ref subtype, seems so. The ref property itself is # thus not inherited. type NonRefSubBanana = object of Banana # Base reduction is just zero, override in subtypes. # Made this a method to see if we can override it with a proc. method reduction*(self) :Dollar = Dollar(0) # Override with a proc. Humpty dumpty, should bind statically # for Bananas, otherwise call the one above. proc reduction*(self: Banana) :Dollar = Dollar(9) # Our base implementation just makes sure we round off # to nearest cent and subtracts any reduction. import math proc calcPriceProc*(self) :Dollar = Dollar(round(self.price.float * 100)/100 - self.reduction().float) # Lets implement it smarter for Pumpkins. Here we convert # to a Fruit in order to call the \u0026#34;super\u0026#34; implementation. proc calcPriceProc*(self: Pumpkin) :Dollar = Dollar(calcPriceProc(Fruit(self)).float * self.weight.float) # BigPumpkin - 1000 bucks! Take it or leave it! # This is a method overriding the base proc method calcPriceProc*(self: BigPumpkin) :Dollar = Dollar(1000) # A base implementation too, but as a method instead of a proc. method calcPriceMethod*(self: Fruit) :Dollar = Dollar(round(self.price.float * 100)/100 - self.reduction().float) # And a method similarly for Pumpkins, hum... # We can\u0026#39;t use the type conversion \u0026#34;super call\u0026#34; technique - because methods # dispatch on runtime type - so how can we call the method above??? # We can\u0026#39;t, fall back on calling the base proc instead. method calcPriceMethod*(self: Pumpkin) :Dollar = Dollar(calcPriceProc(Fruit(self)).float * self.weight.float) Phew! So the above little fruit library sets up some trivial inheritance and adds some procs and methods to these object types which we want to play with to see how the inheritance works. Now, the following code uses the above library:\nimport fruit # Create some fruits, normally one would not use constructor # syntax like this, instead call a proc in the fruit module # that does it for us, encapsulation. var p = Pumpkin(origin: \u0026#34;Africa\u0026#34;, price: 10.00111.Dollar, weight: 5.2.Kg) var b = Banana(origin: \u0026#34;Liberia\u0026#34;, price: 20.00222.Dollar) var bp = BigPumpkin(origin: \u0026#34;Africa\u0026#34;, price: 10.Dollar, weight: 15.Kg) # BigPumpkins have a method overriding the base proc, it works! assert(bp.calcPriceProc() == 1000.Dollar) # Works for Banana, uses Fruit base proc, we see it rounds to cents # and it also then make a self call to reduction() for Bananas. assert(b.calcPriceProc() == 11.0.Dollar) # Works for Pumpkin, static binding. Rounds to cents (the super call) # and multiplies with weight. No reduction, correct. assert(p.calcPriceProc() == 52.0.Dollar) # What happens in a proc generalized for Fruits? Type info is lost so # static binding will bind to base implementation regardless of what x is. proc testingProcs(x: Fruit) :Dollar = # Here the type of x is Fruit x.calcPriceProc() # Lets call the above proc and see... # Oops, the self send reduction() misses that its a Banana! assert(testingProcs(b) == 20.Dollar) # Should be 11 # Oops, the override of calcPriceProc() for Pumpkins is also missed! assert(testingProcs(p) == 10.0.Dollar) # Should be 52 # But with generics it works just fine... We can also constrain it to # only accept Banana and Pumpkin. proc testingProcsGeneric[T: Banana|Pumpkin](x: T) :Dollar = # Here Nim will produce multiple variations of this method, for both Banana # and Pumpkins (call sites below), so type information is not lost. # It should call the correct proc. x.calcPriceProc() # All good with generics assert(testingProcsGeneric(b) == 11.0.Dollar) assert(testingProcsGeneric(p) == 52.0.Dollar) # If we call a method the type of x doesn\u0026#39;t matter, its the type of the object # itself that counts. proc testingMethods(x: Fruit) :Dollar = # Here we will dispatch dynamically x.calcPriceMethod() # All good... or??? Oops, the reduction for Bananas is lost! assert(testingMethods(b) == 20.0.Dollar) # Should be 11 # The override for Pumpkin works fine assert(testingMethods(p) == 52.0.Dollar) echo \u0026#34;All good, well, or at least we got what the comments said.\u0026#34; Did you follow all that? Really? Then explain it to me! :)\nBasically, mixing procs and methods \u0026hellip; is tricksy.\nSo let\u0026rsquo;s shorten, remove comments, regroup code into \u0026ldquo;classes\u0026rdquo; and only use methods. To solve the \u0026ldquo;super call\u0026rdquo; we throw in a template so that we can reuse that code in two different methods. Not the same, but ok:\nimport math # Dollars and Kgs type Dollar* = distinct float Kg* = distinct float proc `$`*(x: Dollar) :string = $x.float proc `==`*(x, y: Dollar) :bool {.borrow.} # Fruit class type Fruit* = ref object of RootObj origin*: string price*: Dollar method reduction*(self: Fruit) :Dollar = Dollar(0) # Code broken out in a template for reuse, since super call doesn\u0026#39;t # fly with methods yet. template basePrice(): Dollar = Dollar(round(self.price.float * 100)/100 - self.reduction().float) method calcPrice*(self: Fruit): Dollar = # Use template, zero cost basePrice() # Banana class type Banana* = ref object of Fruit size*: int method reduction*(self: Banana): Dollar = Dollar(9) # Pumpkin type Pumpkin* = ref object of Fruit weight*: Kg method calcPrice*(self: Pumpkin) :Dollar = # Use template, zero cost Dollar(basePrice().float * self.weight.float) # BigPumpkin type BigPumpkin* = ref object of Pumpkin method calcPrice*(self: BigPumpkin) :Dollar = Dollar(1000) And the code testing it:\nimport fruit var p = Pumpkin(origin: \u0026#34;Africa\u0026#34;, price: 10.00111.Dollar, weight: 5.2.Kg) var b = Banana(origin: \u0026#34;Liberia\u0026#34;, price: 20.00222.Dollar) var bp = BigPumpkin(origin: \u0026#34;Africa\u0026#34;, price: 10.Dollar, weight: 15.Kg) assert(bp.calcPrice() == 1000.Dollar) assert(b.calcPrice() == 11.0.Dollar) assert(p.calcPrice() == 52.0.Dollar) # What happens in a proc generalized for Fruits? Type info is lost # but since we now use only methods, it doesn\u0026#39;t matter proc testing(x: Fruit) :Dollar = x.calcPrice() assert(testing(b) == 11.Dollar) assert(testing(p) == 52.0.Dollar) assert(testing(bp) == 1000.Dollar) echo \u0026#34;All good with only methods.\u0026#34; What I learned from the above:\nSingle inheritance works fine in Nim, no surprises really. Sure, procs and methods are defined \u0026ldquo;on their own\u0026rdquo; but there is no practical difference. Procs bind statically and calling a \u0026ldquo;super\u0026rdquo; proc is easy using type conversion. But\u0026hellip; if the super method calls other methods\u0026hellip; ouch! Type info lost! Better to use templates or similar as above. If we don\u0026rsquo;t use generics but instead use base types (like Fruit) for arguments, we will \u0026ldquo;lose\u0026rdquo; type information, and potentially we \u0026ldquo;miss\u0026rdquo; calling our overrides! Not a surprise to a hardcore static guy, but\u0026hellip; as a dynamic typing dude - this is a gotcha! Using methods only of course avoids that issue. Methods and procs can be mixed, but here there be dragons. I think. If we use methods we currently can\u0026rsquo;t call a \u0026ldquo;super\u0026rdquo; method. Workaround today is to factor out the base implementation, for example in a template, as done above. UPDATE: See part IV about this. If we use procs only and apply generics (I did but didn\u0026rsquo;t bother including that code), it works perfectly fine too in this example. But as noted, do not use type conversion to a base type to do super calls, unless you are sure what you are doing. :) If you have several classes like this in the same module, take care of the order of procs - make sure your overrides are defined before their uses. Otherwise you can easily end up calling a base implementation, just because the compiler hasn\u0026rsquo;t seen the override definition yet! Remark Link to heading Phew. In summary I would say the OO features are mostly there. Super calls (for both procs and methods I would say) is evidently a \u0026ldquo;hole\u0026rdquo; in the language, I think it needs some kind of solution. But coding and testing is a very nice experience, its not that hard to get into it. But I would say it will take some practice before you know what routes are available for OO in Nim.\nConclusion Link to heading I have only begun discovering Nim so I have yet to see how OO works in a larger Nim codebase. I also haven\u0026rsquo;t really explored lambdas and several of the datatypes yet, nor macros and templates and lots of other things. But I feel confident that Nim can do OO code quite well.\nGo Nim!\n"},{"title":"Nim Socket Server","permalink":"https://goran.krampe.se/2014/10/25/nim-socketserver/","summary":"\u003cp\u003eIn learning \u003ca href=\"http://nim-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNim\u003c/a\u003e\n I decided to implement a trivial Socket server, very small, as an example. Its \u003cstrong\u003enot a useful HTTP server\u003c/strong\u003e (it just returns a hard coded HTTP response so we can benchmark it using HTTP tools), and its \u003cstrong\u003enot async\u003c/strong\u003e - there are other such examples in the Nim examples directory and in its stdlib. No, I wanted to write a more classical threaded socket server to see how easy that is - especially with the new APIs in Nim \u003ca href=\"https://github.com/Araq/Nimrod/tree/bigbreak\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u0026ldquo;bigbreak\u0026rdquo;\u003c/a\u003e\n - and see how it performs.\u003c/p\u003e\n\u003cp\u003eThe new \u0026ldquo;bigbreak\u0026rdquo; branch that will become Nim 0.10.0 soon-ish has a bunch of new stuff in the networking area. Its replacing the single \u003ccode\u003esockets\u003c/code\u003e module with a low level \u003ccode\u003erawsockets\u003c/code\u003e module, and a higher level \u003ccode\u003enet\u003c/code\u003e module. And there is a new \u003ccode\u003eselectors\u003c/code\u003e module that abstracts over different modern IO polling mechanisms. This means that a single API will use \u003cstrong\u003eepoll on Linux, kqueue on BSD/OSX, old select on the other Unices and IO Completion ports on Windows\u003c/strong\u003e. At the moment epoll, select on \u0026ldquo;other Unices\u0026rdquo; and IO Completion ports works. kqueue is on the todo.\u003c/p\u003e\n\u003cp\u003eSo without further ado\u0026hellip;\u003c/p\u003e","content":"In learning Nim I decided to implement a trivial Socket server, very small, as an example. Its not a useful HTTP server (it just returns a hard coded HTTP response so we can benchmark it using HTTP tools), and its not async - there are other such examples in the Nim examples directory and in its stdlib. No, I wanted to write a more classical threaded socket server to see how easy that is - especially with the new APIs in Nim \u0026ldquo;bigbreak\u0026rdquo; - and see how it performs.\nThe new \u0026ldquo;bigbreak\u0026rdquo; branch that will become Nim 0.10.0 soon-ish has a bunch of new stuff in the networking area. Its replacing the single sockets module with a low level rawsockets module, and a higher level net module. And there is a new selectors module that abstracts over different modern IO polling mechanisms. This means that a single API will use epoll on Linux, kqueue on BSD/OSX, old select on the other Unices and IO Completion ports on Windows. At the moment epoll, select on \u0026ldquo;other Unices\u0026rdquo; and IO Completion ports works. kqueue is on the todo.\nSo without further ado\u0026hellip;\n\u0026hellip;here is the code with lots of comments sprinkled all over it - so that hopefully even a non Nim programmer can understand how it works:\n# Imports are by source, so this will import threadpool.nim, net.nim etc # from ../lib relative to the location of the nim compiler. Everything # will be compiled together into a single statically linked executable. import threadpool, net, os, selectors, strutils ## A trivial spawning socket server where each connecting socket is handed ## over to the threadpool for handling and response. ## ## * Uses the new \u0026#34;threadpool\u0026#34; module to spawn off the actual handling of each request ## * Uses the new high level socket module called \u0026#34;net\u0026#34; which is above \u0026#34;rawsockets\u0026#34; ## * Uses the new abstract selector from module \u0026#34;selectors\u0026#34; to do efficient polling (epoll etc) ## ## Compile using Nim \u0026#34;bigbreak\u0026#34; with: ## nim c --threads:on --d:release spawningserver.nim ## ## Run it and throw ab on it, 100 concurrent clients: ## ab -r -n 500000 -c 100 http://localhost:8099/ ## ## On my laptop for \u0026#34;bytes = 100\u0026#34; I get about: ## ## Requests per second: 17133.43 [#/sec] (mean) ## Time per request: 5.837 [ms] (mean) ## Time per request: 0.058 [ms] (mean, across all concurrent requests) # Just a regular kind of \u0026#34;Nim class definition\u0026#34; - the type \u0026#34;Server\u0026#34; inheriting # the default root object with a single instance variable \u0026#34;socket\u0026#34; of type # Socket. type Server = ref object of RootObj socket: Socket # Amount of data to send const bytes = 100 # The payload const content = repeatStr(bytes, \u0026#34;x\u0026#34;) # And the response const response = \u0026#34;HTTP/1.1 200 OK\\r\\LContent-Length: \u0026#34; \u0026amp; $content.len \u0026amp; \u0026#34;\\r\\L\\r\\L\u0026#34; \u0026amp; content # This is where we perform the response on the socket. # This proc is spawned off in its own thread on the threadpool. proc handle(client: Socket) = # TaintedString is used for strings coming from the outside, security mechanism. # The below is equivalent to TaintedString(r\u0026#34;\u0026#34;) and TaintedString is a distinct type # of the type string. The \u0026#34;r\u0026#34; means a raw string. var buf = TaintedString\u0026#34;\u0026#34; # Using try:finally: to make sure we close the client Socket # even if some exception is raised try: # Just read one line... and then send our premade response client.readLine(buf, timeout = 20000) client.send(response) finally: # We may end up here if readLine above times out for example, # we just ignore (no raise to propagate further) and close. client.close() # Eternal loop where we use the new selectors API. # If we get an event on the listening socket # we create a new Socket and accept the connection # into it. Then we spawn the handle proc. proc loop(self: Server) = # Create a Selector - cross platform abstraction for polling events. var selector = newSelector() # Register our listener socket\u0026#39;s file descriptor, the events we want to wait for # and an optional user object associated with this file descriptor - we just use nil # since we are only listening on one Socket. discard selector.register(self.socket.getFD, {EvRead}, nil) while true: # Ask selector to wait up to 1 second, did we actually get a connection? if selector.select(1000).len \u0026gt; 0: # Socket is a ref object, so \u0026#34;Socket()\u0026#34; will allocate it on the heap. # Perhaps a bit needless since we will deepCopy it two lines down in spawn. var client: Socket = Socket() # Or like this, its equivalent: # var client: Socket # new(client) accept(self.socket, client) # Spawn it off into the new threadpool - nifty stuff. It is a self adapting # thread pool that checks number of cores etc. The argument is deepCopied over # ensuring threads do not share data. spawn handle(client) # We create a listening port and then call loop() which does not return proc listen(self: Server, port: int) = # First we create a Socket. newSocket is a convenient proc with good # default values. self.socket = newSocket() # Hmmm, where is InvalidSocket defined in bigbreak? #if self.socket == sockets.InvalidSocket: raiseOSError(osLastError()) # Then we bind/listen and call the loop. Whichever way we exit the try: # block (exception raised or a normal return) Nim will call the finally: # block for cleanups where we make sure to close the socket. try: self.socket.bindAddr(port = Port(port)) self.socket.listen() echo(\u0026#34;Server listening on port \u0026#34; \u0026amp; $port) self.loop() finally: self.socket.close() # Only compiled when this is not used as a module when isMainModule: # Type inference makes port an int var port = 8099 # Type inference makes server a Server, which is # a \u0026#34;ref\u0026#34; to an \u0026#34;object\u0026#34;, see type definition at top. # If you call a ref object type like this - it acts # like a constructor and will use new to allocate the # type ref\u0026#39;ed on the heap. var server = Server() # The listen proc takes a Server as first param server.listen(port) Remarks on code Link to heading Here are some things to note:\nOn line 46 we see TaintedString\u0026quot;\u0026quot;which may look odd. Its equivalent to TaintedString(r\u0026quot;\u0026quot;) and that is actually a so called type conversion of a raw string . A TaintedString is (with --taintMode:on) a distinct type of string. So it \u0026ldquo;works\u0026rdquo; the same as string, but is another type according to the type system and thus way we can track the use of this string more closely. More on TaintedString . NOTE: Compilation fails with taintMode:on currently, something doesn\u0026rsquo;t handle it properly in net On line 64-71 we see trivial use of the new selectors module. The user object we send in as nil would typically be some object with a reference to the Socket, so when we call select (line 71) and get a sequence back with those user objects that had the event (we listen for EvRead in this case) - we don\u0026rsquo;t need to do some lookup based on the Socket itself. In this code however we only listen on a single listener Socket, so we just want to know if the sequence wasn\u0026rsquo;t empty (len \u0026gt; 0), meaning that we did get an event for our listening socket. On line 74-78 we create a new Socket (it was called PSocket earlier, in \u0026ldquo;bigbreak\u0026rdquo; its been renamed to Socket) and since Socket is a \u0026ldquo;ref object\u0026rdquo; type it will implicitly call the new proc which allocates it on the heap. Then later on line 78 we call accept and the accept will \u0026ldquo;fill in the details\u0026rdquo; in this new Socket object. The client parameter is a \u0026ldquo;var parameter\u0026rdquo; so in theory the accept procedure could assign to it - but it turns out this is a leftover from earlier code - because it doesn\u0026rsquo;t assign to it. Personally I am still slightly uneasy with the fact that I can\u0026rsquo;t really tell from the call here that the client var can be modified to reference another Socket. But I also understand that having some annotation on the call site would make the code less readable. On line 82 we do spawn and that will cause the argument (the Socket) to be deepCopied and handed over to another thread, making sure the threads are isolated from each other. Performance Link to heading Some notes before discussing the numbers:\nThis code doesn\u0026rsquo;t do any keep-alive, its all just lots of connect/recv-and-send/close. I only ran ab against localhost from localhost, so may be less realistic. This code doesn\u0026rsquo;t really do anything in the handler. We basically measure spawn and socket accept/close overhead per request. And shoveling data. And the verdict:\nFor a trivial payload of 100 bytes and 100 concurrent we get 17k req/sec each taking 5-12 ms, note that we do 100 in parallell. If we increase concurrency to 1000 we still do about 15k req/sec each taking 20-28ms. Personally I felt these are good numbers, but I admit I need to compare with say Nginx or Nodejs or something. A slighty bigger payload of 100000 bytes and 100 concurrent we get 11k req/sec each taking 9-17ms, serving in total about 1Gb/sec. For a fat payload of 2Mb and 100 concurrent we get around 8k req/sec but a whopping 1.5Gb/sec. I also verified that Nim sets up a thread pool (about 40 threads it seemed to use on my machine) and most of the utilization is focused around 5 threads - presumingly matching my 4 cores. But it was quite satisfying to watch the system monitor and see that all 4 cores are happily working :)\nIf you remove the spawn word then this turns into a synchronous server handling just one request at a time sequentially. You can then test with ab using a single client. It actually does a bit more requests per second then, about 22k I think I got. This is most probably due to the fact that we get rid of the \u0026ldquo;spawn overhead\u0026rdquo; so the listener forking off sockets will loop a tad faster even though it does the read-send-close in the loop.\nConclusion Link to heading The code is short and clean, perhaps its not fully Nimiomatic - I use \u0026ldquo;self\u0026rdquo; as the name for \u0026ldquo;this\u0026rdquo;, not sure what OO Nimmers tend to use. It was fun to write and performance seems very good to me. It\u0026rsquo;s also quite stable and I can\u0026rsquo;t see any memory leaking. :)\nThe thread pool mechanism is very promising (great work there Andreas!) and its also very neat that we can have epoll based polling with just a few lines of code - and its meant to work cross platform. Way to go Dominik! :)\n"},{"title":"I missed Nim","permalink":"https://goran.krampe.se/2014/10/20/i-missed-nim/","summary":"\u003cp\u003eA year ago I wrote an article trying to round up \u003ca href=\"http://goran.krampe.se/2013/09/07/new-languages-this-century\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003enew languages since year 2000\u003c/a\u003e\n and what I think of them by just\u0026hellip; glancing at them, or otherwise playing with them. I ended up sifting out the 4 most interesting in my not so humble opinion - \u003ca href=\"http://golang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eGo\u003c/a\u003e\n, \u003ca href=\"http://www.rust-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eRust\u003c/a\u003e\n, \u003ca href=\"http://dartlang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eDart\u003c/a\u003e\n and \u003ca href=\"http://julialang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eJulia\u003c/a\u003e\n. Now a year has passed and\u0026hellip;\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eI discover that I missed Nim(Nimrod)!\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://nim-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNim\u003c/a\u003e\n was born somewhere around 2006-ish and is clearly a very serious language to consider, but is going suspiciously under the radar. Having reviewed this language more closely (and still doing so) I can safely say that \u003cstrong\u003efor me\u003c/strong\u003e it actually easily \u003cstrong\u003etops this list\u003c/strong\u003e.\u003c/p\u003e\n\u003cp\u003eI have already posted \u003ca href=\"http://goran.krampe.se/categories/nim\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ea few articles about Nim\u003c/a\u003e\n, but this one is meant as a \u003cem\u003efollowup\u003c/em\u003e to \u003ca href=\"http://goran.krampe.se/2013/09/07/new-languages-this-century\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ethat article\u003c/a\u003e\n trying to make amends :).\u003c/p\u003e\n\u003cp\u003e\u003cem\u003e\u003cstrong\u003eNOTE:\u003c/strong\u003e Technically \u003ca href=\"http://nim-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNim\u003c/a\u003e\n is still called \u0026ldquo;Nimrod\u0026rdquo; up to and including the \u003ca href=\"http://nim-lang.org/news.html#Z2014-10-19-version-0-9-6-released\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003e0.9.6-release that was done yesterday\u003c/a\u003e\n. But for the upcoming 0.10.0 and onward its \u003cstrong\u003eNim\u003c/strong\u003e. Short and sweet.\u003c/em\u003e\u003c/p\u003e","content":"A year ago I wrote an article trying to round up new languages since year 2000 and what I think of them by just\u0026hellip; glancing at them, or otherwise playing with them. I ended up sifting out the 4 most interesting in my not so humble opinion - Go , Rust , Dart and Julia . Now a year has passed and\u0026hellip;\nI discover that I missed Nim(Nimrod)!\nNim was born somewhere around 2006-ish and is clearly a very serious language to consider, but is going suspiciously under the radar. Having reviewed this language more closely (and still doing so) I can safely say that for me it actually easily tops this list.\nI have already posted a few articles about Nim , but this one is meant as a followup to that article trying to make amends :).\nNOTE: Technically Nim is still called \u0026ldquo;Nimrod\u0026rdquo; up to and including the 0.9.6-release that was done yesterday . But for the upcoming 0.10.0 and onward its Nim. Short and sweet.\nWhat kind of language is Nim? Link to heading Nim is a statically typed imperative language (not primarily functional, nor OO - but can do most of it) with a whole slew of advanced compilation techniques. At the same time it strives to be \u0026ldquo;programmable\u0026rdquo; with a very clean and noiseless indentation based syntax.\n# Fizz Buzz program const f = \u0026#34;Fizz\u0026#34; const b = \u0026#34;Buzz\u0026#34; for i in 1..100: if i mod 15 == 0: echo f, b elif i mod 5 == 0: echo b elif i mod 3 == 0: echo f else: echo i Readable? Definitely.\nI would say not many languages today manage to combine the above. Most advanced statically typed languages completely SUCK in the programmability department. Unless you are some genius of course. In the quest for speed and features most of these languages totally miss the boat on making a language that is actually easy to use.\nNow\u0026hellip; have no doubt, Nim is a pretty darn advanced language - and personally I tend to shun those. I like minimal languages and I have dwelled in the realm of Smalltalk minimalism for a long time, and as a Smalltalker I am also accustomed to a very high level of productivity, interactivity and sophistication of development environment. Nim may be productive once you get going - in fact - many people say they indeed are. But when it comes to interactivity and development environment, its very \u0026hellip; early in the game.\nBut still this language is getting to me, against all odds. I can\u0026rsquo;t even remember when I last felt this interested in a statically typed language.\nAndreas Rumpf, the designer and main implementor of the language and compiler (written in Nim of course) has an interesting balance between enabling very advanced compiler techniques and still - at least as it seems - maintain a language that is actually usable by \u0026ldquo;normal people\u0026rdquo;.\n\u0026ldquo;Nimrod is a statically typed programming language that tries to give the programmer ultimate power without compromises on runtime efficiency.\u0026rdquo; — Andreas Rumpf\nAndreas has borrowed heavily from a range of different languages: Modula 3, Delphi, Ada, C++, Python, Lisp, Oberon. Notably several from \u0026ldquo;Pascal descent\u0026rdquo; and dare I also say, Windows centered languages? Just a guess, Andreas works primarily on Windows I think.\nThis little list of examples of borrowing was mentioned in the forum by Andreas:\nMacro system inspired by Lisp. Export marker taken from Oberon. Argument passing semantics taken from Ada. distinct types inspired by Ada. Syntax also heavily influenced by Python. Generics inspired by C++. The 3 pointer like types ptr, ref, var taken from Modula 3. async / await stolen from C#. let taken from ML. Let\u0026rsquo;s now look at Nim vs those four I identified; Go, Julia, Dart and Rust. When contrasting with Nim, and also looking at where these languages have gone during the year since I wrote that article - things are a bit more clear.\nJulia is very focused on math and is a dynamically typed language, still very interesting but clearly targetting the scientific community - its definitely not really competing with Nim - its too different. It is also LLVM-based and as such has different characteristics on platform availability. Julia does however have a sophisticated macro system, just like Nim.\nDart is focusing on the web, much more so than I had hoped. Perhaps it will turn \u0026ldquo;general purpose\u0026rdquo; eventually, but evidently Google is trying to push it hard as a web dev tool. Its also dynamically typed (yes it is) and also too different to really overlap with Nim.\nThis leaves us Go and Rust which we can look a bit closer at.\nNim vs Go Link to heading Go seems to be a \u0026ldquo;C made developer friendly\u0026rdquo; and that\u0026rsquo;s not strange given its creators of course, but as others point out , it doesn\u0026rsquo;t really bring much new stuff and is not particularly well designed - so people say that have actually used it :)\nIt is fairly popular however, and that is probably due to its C-syntax, being fairly fast and compiling to native, sticking to relatively simple constructions, ease of use and being backed by Google. The net effect is that its seductively easy to get going with. It seems to be picking up users both from dynamically and statically typed camps. Go is relatively stable by now and that\u0026rsquo;s also important to adoption.\nCompared to Nim then\u0026hellip; Go is in some ways attracting a similar crowd - people who want a language that is productive, but not sacrificing speed. One can see several similarities around ease of use, like fast and simple compilation, easy package management and so on. Obviously there is a common feeling that things can be done simpler these days - and both Nim and Go developers share that idea. But there are BIG differences, here just a few highlighted:\nGo has no macros, no generics, no overloading, no object variants and\u0026hellip; let\u0026rsquo;s just say a much less sophisticated type system. Its very much \u0026ldquo;less\u0026rdquo;. Both Go and Nim has similar concurrency models centered around non shared memory and asynchronous communication between them. Nim has optional GC, and its soft realtime, per thread. Go is GC only. Nim has optional pointers and low level mechanisms, if you want to. This way it matches areas where C would be applicable. Go doesn\u0026rsquo;t go there. It seems though that perhaps people are \u0026ldquo;waking up\u0026rdquo; disillusioned in Go land, just like many did after getting seduced by NodeJS. This article pinpoints it quite well . My conclusion is that while the tooling, standard libraries and community around Go is excellent - the language itself is NOT, like others might describe in much harsher words .\nNim vs Rust Link to heading Ok, so this is where the real battle lies and the lines get blurred. It looks evident that Rust is much more complicated to program in. Rust is also very much focused on safety, safety, safety, while Nim is more focused on being practical and pragmatic.\nThe main popular selling point of Rust is its memory model with a combination of different kinds of pointers and scope based allocation/deallocation making it all automatic while not needing a GC. But just like Nim it also has a sophisticated type system and well, these languages seem quite similar in feature sets.\nHere are some differences at least, but I know both languages too little to give more discriminating details:\nRust is \u0026ldquo;C syntax\u0026rdquo; and Nim is Python-ish. Nim wins this one hands down for me. Nim has Exceptions with tracking (!) and Rust has explicit error handling via the return value . Personally\u0026hellip; that feels like a big step backwards, much like error handling in Go. Again, for me, a clear win for Nim. I know others feel differently, but that is ok :) Rust is pushed by Mozilla, Nim is a grass root \u0026ldquo;true open source\u0026rdquo; language. Having a \u0026ldquo;backer\u0026rdquo; might be good, but I like grass root efforts since they tend to be more open and easier to participate in as a \u0026ldquo;full\u0026rdquo; member. UPDATE 2014-11-08: I know both languages are open source and have communities. But it remains a fact that Rust is lead by Mozilla (I would be surprised if not) and Nim is lead by its community. That doesn\u0026rsquo;t necessarily mean one way is better than the other though. Regarding the error handling in Rust - I have edited the above text to point to the relevant current section in the Rust documentation. I would however urge Rust people to add a section in their documentation called \u0026ldquo;Error handling\u0026rdquo; or similar so that one can find it without having to read the entire manual! UPDATE 2016-01-26: And today there is such a section , I have also read from several sources that Mozilla is not leading the Rust development anymore, but I don\u0026rsquo;t know the details.\nI think the discussion here sums up what several people feel about Nimrod vs Rust.\nI think Rust is going places, but I don\u0026rsquo;t feel attracted to it. Every time I read about it - I get too overwhelmed by the complexity. It does feel like C++ all over again, although perhaps without the segfaults :)\nConclusion Link to heading My only conclusion is that I am glad I have found Nim and although the feature set is a bit overwhelming (especially if you just read the language manual) I wouldn\u0026rsquo;t say the code I have read so far is in any way hard to read, on the contrary. I conclude that it is possible to make an advanced language while still crafting it in such a way that its practical to use. But that takes considerable devoted effort - and Andreas Rumpf seems to be pulling this off.\nI also highly appreciate the fact that I can \u0026ldquo;chip in\u0026rdquo; and actually make a difference in the development and future directions of Nim - given its highly open, friendly and communicative community. I am used to another very friendly community (Smalltalk) and so far I am equally impressed by the Nim community.\nGo Nim!\n"},{"title":"Nim wrapping C","permalink":"https://goran.krampe.se/2014/10/16/nim-wrapping-c/","summary":"\u003cp\u003eNim has all the language mechanisms needed to smoothly interoperate with C and C++. The rather \u003ca href=\"https://github.com/Araq/Nimrod/tree/devel/lib/wrappers\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003elarge collection of wrapped C libraries\u003c/a\u003e\n (and that\u0026rsquo;s only those in the standard libs) is also a testament to this fact. In this article I explain my personal findings testing out the waters of wrapping a simple C library.\u003c/p\u003e\n\u003cp\u003eThe basic approach to wrapping a simple C library is:\u003c/p\u003e\n\u003col start=\"0\"\u003e\n\u003cli\u003eInstall Nim.\u003c/li\u003e\n\u003cli\u003eInstall c2nim using Babel or manually clone c2nim from github and build it.\u003c/li\u003e\n\u003cli\u003eUse c2nim to translate the C header file(s) to a so called Nim wrapper.\u003c/li\u003e\n\u003cli\u003eMake a small test showing it works.\u003c/li\u003e\n\u003cli\u003eWrite a so called \u003cem\u003e\u0026ldquo;impure\u0026rdquo;\u003c/em\u003e intermediary library that uses the wrapper (next article)\u003c/li\u003e\n\u003cli\u003eMake a test green and declare Victory (next article)\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eOkidoki\u0026hellip; (roll up sleeves)\u003c/p\u003e","content":"Nim has all the language mechanisms needed to smoothly interoperate with C and C++. The rather large collection of wrapped C libraries (and that\u0026rsquo;s only those in the standard libs) is also a testament to this fact. In this article I explain my personal findings testing out the waters of wrapping a simple C library.\nThe basic approach to wrapping a simple C library is:\nInstall Nim. Install c2nim using Babel or manually clone c2nim from github and build it. Use c2nim to translate the C header file(s) to a so called Nim wrapper. Make a small test showing it works. Write a so called \u0026ldquo;impure\u0026rdquo; intermediary library that uses the wrapper (next article) Make a test green and declare Victory (next article) Okidoki\u0026hellip; (roll up sleeves)\nJust do it Link to heading I have a thing for new cool NoSQL databases and one of the coolest bad ass NoSQL databases that isn\u0026rsquo;t that well known is HyperDex . HyperDex doesn\u0026rsquo;t have a published \u0026ldquo;over the wire\u0026rdquo; protocol - the approach to interface with it is to use their C client library which is very simple in its design so that its easy to wrap in various client languages. They support the usual suspect languages - but of course not Nim. Bastards! :)\n0. Get Nim Link to heading Not going into details here, this works for me on Ubuntu:\nGet Nim . I used the source bootstrap at the bottom there, and wrote about it in excrutiating detail too . Get Babel (package manager). At the moment Babel is in a bit of flux since Dominik is renaming it to Nimble. But I got a slightly older commit to work: git clone https://github.com/nimrod-code/nimble.git cd nimble git checkout 7d18e2be1cdd4043f61918eae4a9877a90a296a4 nimrod c -r src/babel install 1. Getting c2nim Link to heading The trivial way to get c2nim is to use Babel:\nbabel install c2nim\nAnd that\u0026rsquo;s that. :)\nAnother option is to get c2nim manually from github , but building it (nimrod c c2nim) hit a little snag:\nc2nim.nim(11, 33) Error: cannot open 'llstream'\n\u0026hellip;some file searching later I note this is a module that is part of the Nimrod compiler itself. How come its not found? I checked in Babel etc, but no dice. Then I ended up trying out nimrod dump (see nimrod --advanced) and aha, the paths at the end looks weird, it tries to find compiler in /usr/local/compiler. I suspect it tries to locate it relative to the nimrod binary as ../compiler which would work if we hadn\u0026rsquo;t installed nimrod into /usr/local/bin and instead would be running it directly from the github clone.\nOk, then - I give up and do as \u0026ldquo;the Romans\u0026rdquo; - don\u0026rsquo;t install Nim but use it directly from the clone by linking it into your path. So I ran deinstall.sh from the github clone I installed:\nsudo sh deinstall.sh /usr/local/bin\n\u0026hellip;and then linked the nimrod binary into my PATH. After this compiling worked just fine. I also learned however that I can add search paths manually, so this also worked:\nnimrod -p:../Nimrod.devel/compiler/ c c2nim\n2. Using c2nim Link to heading I am no super C guru. Things that are obvious to the other Nimmers may not be for me. So\u0026hellip; first of all I had a rather dim view on what c2nim is meant to do - convert a C file to Nim? How will that actually help me make a wrapper for a C library?\nI looked at some example wrappers, you can find them in lib/wrappers like say lib/wrappers/sqlite3.nim and from my googling I suspected these have been created using c2nim. Things to note in the sqlite3 example:\nMost wrappers tend to use dead code elimination - deadCodeElim pragma, I guess it works fine for this kind of Nim module (it turns out c2nim adds this pragma on its own when we use the dynlib pragma) There is a little when-section in the beginning. This is compile time logic, which is neat. The pattern used in the string for the library .so name is specific for the dynlib pragma . Each proc has some pragmas associated {.cdecl, dynlib: Lib, importc: \u0026quot;sqlite3_last_insert_rowid\u0026quot;.} that makes it tick. Ok, time to dance. First I copied the header file I wanted to use to my c2nim directory, since I probably will need to adjust/clean it. But when I first just naively ran c2nim hyperclient.h I didn\u0026rsquo;t get that when-section nor any pragmas attached to the proc declarations. It did quite fine translating typedefs, structs, enums etc to the Nim equivalents though.\nWhat does the c2nim manual say ? Hmmm, still not obviously clear to me - especially how the pragmas are meant to be used. But my understanding so far is that:\nWe need cdecl so that the proc uses C convention for calls. We need dynlib: Lib (where Lib is the string var for the library name from the when-section) so that this proc actually maps into that library. We need the importc: \u0026quot;blablabla\u0026quot; pragma to actually map the proc to the proper function in the library. Since reading manuals sometimes is not my strongest side I started trying it out using the options to c2nim, and came up with this incantation that actually seemed to do the right things:\n./c2nim --prefix:hyperclient_ --dynlib:libname --cdecl hyperclient.h --out:hyperclient.nim\nRunning c2nim --help got me guessing these and yes it works, but I still have to add the when-section manually, hrm. But reading some more the manual reveals how this can be added in the header file instead, so I edited the hyperdexclient.h accordingly:\nRemoved some includes, they aren\u0026rsquo;t used by c2nim anyway. Added a when section using #ifdef C2NIM as described in the manual section linked above, see below how it looks. Added my pragma options to the same section (dynlib, cdecl, prefix) Copied the contents of hyperdex.h into hyperdexclient.h, it was included using #include and it only contains some simple stuff so simpler to have a single header file. A clever reader realizes that the above steps could be automated of course, perhaps in Nim! :) The section at the top now looks like:\n#ifdef C2NIM # dynlib libname # cdecl # prefix hyperclient_ # if defined(windows) # define libname \u0026#34;libhyperclient.dll\u0026#34; # elif defined(macosx) # define libname \u0026#34;libhyperclient.dylib\u0026#34; # else # define libname \u0026#34;libhyperclient.so\u0026#34; # endif #endif So now we can simply run ./c2nim hyperdexclient.h and it will produce a hyperdexclient.nim with the proper Nim stuff:\n{.deadCodeElim: on.} when defined(windows): const libname* = \u0026#34;libhyperclient.dll\u0026#34; elif defined(macosx): const libname* = \u0026#34;libhyperclient.dylib\u0026#34; else: const libname* = \u0026#34;libhyperclient.so\u0026#34; \u0026hellip;and here we note the sudden appearance of deadCodeElim. If we peek in c2nim we find that it adds it if we use dynlib pragma. Looking further down we can see how the pragmas got inserted into the proc declarations:\nproc create*(coordinator: cstring; port: uint16_t): ptr hyperclient {.cdecl, importc: \u0026#34;hyperclient_create\u0026#34;, dynlib: libname.} I defined the cdecl calling convention since its the standard on Linux and most C compilers, I guess its what 99% of all wrappers use? And the above proc gets mapped to the hyperclient_create function in the library (note how we have stripped the hyperclient_ prefix, since all these functions use it) and we point to the dynamically loaded library named by the libname variable.\nIts damn funky and perhaps confusing to newbies that Nim has compile time execution (macros etc) in Nim and not some other inferior stupid language like the C preprocessor. Of course, as a Smalltalker its the Obvious Right Thing.\nBut\u0026hellip; actually compiling this file BARFS:\n/home/gokr/nim/c2nim/hyper/hyperclient.nim(108, 41) Error: undeclared identifier: \u0026#39;uint16_t\u0026#39; Mmmm, right. So c2nim didn\u0026rsquo;t convert those guys, they are in an include called \u0026lt;stdint.h\u0026gt;. Google to the rescue, oh, so in the zmq4 wrapper it was fixed like this:\ntype size_t* = uint uint16_t = uint16 int32t = int32 uint8_t = uint8 So I did the same:\ntype uint16_t = uint16 uint64_t = uint64 int64_t = int64 And then it builds fine :). But this requires manual editing of the nim file after running c2nim. Perhaps we can do something in the header file? It turns out we can, Araq mentions on IRC that we can use #mangle as described in the manual page (duh\u0026hellip;):\n#ifdef C2NIM # dynlib libname # cdecl # prefix hyperclient_ # if defined(windows) # define libname \u0026#34;libhyperclient.dll\u0026#34; # elif defined(macosx) # define libname \u0026#34;libhyperclient.dylib\u0026#34; # else # define libname \u0026#34;libhyperclient.so\u0026#34; # endif #mangle uint16_t uint16 #mangle uint64_t uint64 #mangle int64_t int64 #endif This will lead to a search-and-replace-all on these matching tokens, but that seems fine for these types. And yup, that works and makes it all cleaner. Wrapper done (we think).\nDoes the Damn Thing Work? Link to heading Yup, it sure seems so! I am on Ubuntu 14.04 and installing HyperDex and firing it up (see Quick start , one coordinator and one daemon is fine) is fairly easy, follow directions on the homepage and you should be golden (although I had to hunt down a deb for libcityhash, weird).\nThen\u0026hellip; I took the C example from HyperDex and translated it into Nim, so it sure looks like crap (well, like C in Nim clothing) but I just wanted to see if the wrapper actually works:\nimport hyperclient # First trivial low level test of the hyperclient.nim wrapper # This is basically Nim as C code. var client: ptr hyperclient attr: attribute attrs: ptr attribute op_status, loop_status: returncode op_id, loop_id: int64 = 0 attrs_sz, i: csize # Get us a client client = create(\u0026#34;127.0.0.1\u0026#34;, 1982) echo(\u0026#34;HyperDex client created.\u0026#34;) # A value to stuff in at key \u0026#34;some key\u0026#34; attr.attr = \u0026#34;v\u0026#34; attr.value = \u0026#34;Hello World!\u0026#34; attr.value_sz = attr.value.len attr.datatype = HYPERDATATYPE_STRING # Perform the \u0026#34;put\u0026#34; stuffing \u0026#34;Hello World!\u0026#34; at \u0026#34;some key\u0026#34; in space \u0026#34;kv\u0026#34; # Nim is friendly and can take string as cstring op_id = put(client, \u0026#34;kv\u0026#34;, \u0026#34;some key\u0026#34;, 8, addr attr, 1, addr op_status) # Wait for it to complete loop_id = loop(client, -1, addr loop_status) # Do at least a minimal error check, this will for example catch if you # missed adding the space in Hyperdex. if op_status != HYPERCLIENT_SUCCESS: quit(\u0026#34;Error: \u0026#34; \u0026amp; $op_status) echo(\u0026#34;Put \\\u0026#34;some key\\\u0026#34; = \\\u0026#34;Hello World!\\\u0026#34;, done.\u0026#34;) # Perform the \u0026#34;get\u0026#34; populating attrs op_id = get(client, \u0026#34;kv\u0026#34;, \u0026#34;some key\u0026#34;, 8, addr op_status, addr attrs, addr attrs_sz) # Wait for it to complete loop_id = loop(client, -1, addr loop_status) if op_status != HYPERCLIENT_SUCCESS: quit(\u0026#34;Error: \u0026#34; \u0026amp; $op_status) # A little helper to do pointer arithmetics, borrowed from: # https://github.com/fowlmouth/nimlibs/blob/master/fowltek/pointer_arithm.nim proc offset[A](some: ptr A; b: int): ptr A = result = cast[ptr A](cast[int](some) + (b * sizeof(A))) # Another helper to make a string from a NON null terminated cstring with a length. proc `$`(x: cstring, len: int): string = result = newString(len) copyMem(addr(result[0]), x, len) # Loop over attrs we got back, print out for i in 0.. \u0026lt;attrs_sz: var a = offset(attrs, i) echo(\u0026#34;Get \\\u0026#34;some key\\\u0026#34; gave back \\\u0026#34;\u0026#34; \u0026amp; (a.value $ a.value_sz) \u0026amp; \u0026#34;\\\u0026#34;, done.\u0026#34;) # Clean up destroy_attrs(attrs, attrs_sz) destroy(client) # Declare success, get coffee. echo(\u0026#34;All done, Nim rocks.\u0026#34;) Some comments that might help:\naddr returns the address of an l-value, see manual . Useful with C libraries. Kinda the opposite of ptr. HyperDex has an asynchronous client library, that\u0026rsquo;s why we need to call loop() for operations to actually be performed and we get an op_id returned to keep track of each operation. In this example its trivial. The offset proc allows us to do pointer arithmetics so we can loop over the attributes returned from the get operation. It can be further refined of course . The $ operator is the Nim polymorphic \u0026ldquo;turn this to a string\u0026rdquo;-operator. In this case it turned out there was no such proc for non null terminated C strings (where you instead have a length). But Araq trivially solved that and since it now takes two arguments it can be invoked in an infix fashion (a.value $ a.value_sz) (see line 58). This may look\u0026hellip; foreign but its already used in someplace in the stdlib, forgot where. Let\u0026rsquo;s try it. First we create a trivial space in HyperDex called \u0026ldquo;kv\u0026rdquo; with key \u0026ldquo;k\u0026rdquo; and attribute \u0026ldquo;v\u0026rdquo;, paste and run in bash:\nhyperdex add-space -h 127.0.0.1 -p 1982 \u0026lt;\u0026lt; EOF space kv key k attribute v EOF Then build test.nim with nimrod c test.nim. On my laptop I get a 177kb executable built in 0.9 seconds. Then we try to run it:\ngokr@yoda:~/nim/c2nim$ time ./test HyperDex client created. Put \u0026#34;some key\u0026#34; = \u0026#34;Hello World!\u0026#34;, done. Get \u0026#34;some key\u0026#34; gave back \u0026#34;Hello World!\u0026#34;, done. All done, Nim rocks. real\t0m0.005s user\t0m0.002s sys\t0m0.002s Phew.\nConclusion Link to heading The wrapping process was quite simple, but a HOWTO like this article would have been great to have! Now perhaps others can go starting wrapping stuff, the C eco system out there is HUGE and IMHO this is one of Nim\u0026rsquo;s big selling points, and one of the primary reasons I am investigating Nim.\nThere will be a followup article on how to make the intermediate layer applying \u0026ldquo;Nimiomatics\u0026rdquo; or \u0026ldquo;Nidiomatics\u0026rdquo; (=idiomatics in Nim), but it might take me a while to get there.\n"},{"title":"Bootstrapping Nim(rod)","permalink":"https://goran.krampe.se/2014/10/15/bootstrapping-nim/","summary":"\u003cp\u003eTechnically \u003ca href=\"http://nim-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNim\u003c/a\u003e\n is still called \u003ca href=\"http://nimrod-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNimrod\u003c/a\u003e\n up to and including upcoming bugfix version 0.9.6. But then with the next version 0.10.0 it will be just \u003cstrong\u003eNim\u003c/strong\u003e. Currently Nimrod is at \u003ca href=\"http://nimrod-lang.org/news.html#Z2014-04-21-version-0-9-4-released\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003e0.9.4\u003c/a\u003e\n. And oh, the current development version is 0.9.5 which will become 0.9.6 when released - the \u0026ldquo;odd and even\u0026rdquo; versioning scheme.\u003c/p\u003e\n\u003cp\u003eNim can be a bit funky to get started with, typically due to a slight lack of documentation in certain areas that may be obvious to Nimmers (or Nimsters? Knights who say Nim?). This article tries to fill a few mental holes in the first steps.\u003c/p\u003e\n\u003cp\u003eAlso, \u003cstrong\u003eNimsters like to do it in Nim\u003c/strong\u003e - and often the reasons for this are very good, like maintaining portability or minimizing dependencies. Just don\u0026rsquo;t expect the classic autoconf dance here. As a Smalltalker I am fully versed in the \u003ca href=\"http://en.wikipedia.org/wiki/Not_invented_here\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNIH syndrome\u003c/a\u003e\n - which of course doesn\u0026rsquo;t always have to be a bad thing. Thankfully Nimmers also seem to balance it with a strong tradition of \u003ca href=\"https://gcc.gnu.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003estanding on the shoulders of giants\u003c/a\u003e\n.\u003c/p\u003e\n\u003cp\u003eSo building Nim isn\u0026rsquo;t \u003cstrong\u003ehard\u003c/strong\u003e, but it\u0026rsquo;s also not \u003cstrong\u003eobvious\u003c/strong\u003e what is going on. There are of course \u003ca href=\"http://nimrod-lang.org/download.html\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ebinary installers\u003c/a\u003e\n available too, but hey, we want to hack!\u003c/p\u003e","content":"Technically Nim is still called Nimrod up to and including upcoming bugfix version 0.9.6. But then with the next version 0.10.0 it will be just Nim. Currently Nimrod is at 0.9.4 . And oh, the current development version is 0.9.5 which will become 0.9.6 when released - the \u0026ldquo;odd and even\u0026rdquo; versioning scheme.\nNim can be a bit funky to get started with, typically due to a slight lack of documentation in certain areas that may be obvious to Nimmers (or Nimsters? Knights who say Nim?). This article tries to fill a few mental holes in the first steps.\nAlso, Nimsters like to do it in Nim - and often the reasons for this are very good, like maintaining portability or minimizing dependencies. Just don\u0026rsquo;t expect the classic autoconf dance here. As a Smalltalker I am fully versed in the NIH syndrome - which of course doesn\u0026rsquo;t always have to be a bad thing. Thankfully Nimmers also seem to balance it with a strong tradition of standing on the shoulders of giants .\nSo building Nim isn\u0026rsquo;t hard, but it\u0026rsquo;s also not obvious what is going on. There are of course binary installers available too, but hey, we want to hack!\nBuilding from source Link to heading Here is the official Unix mantra to build Nim from source:\ngit clone -b master git://github.com/Araq/Nimrod.git cd Nimrod git clone -b master --depth 1 git://github.com/nimrod-code/csources cd csources \u0026amp;\u0026amp; sh build.sh cd .. bin/nimrod c koch ./koch boot -d:release 1. Get the source Link to heading First we clone from github. In Nim country the master is meant to be \u0026ldquo;stable\u0026rdquo;, although still newer than the latest tagged release. The devel branch can also be used, and then we are on the bleeding edge.\n2. Get the C source Link to heading Then we clone out csources. The Nim compiler is written in Nim, so there is an obvious bootstrapping issue here. The approach is that someone (typically Araq - the project leader) who has an old Nim compiler compiles the latest Nim compiler (written in Nim) into C, and then distribute those C files separately in its own github repo, so that everyone can get a first Nim compiler working by simply relying on the existence of a C compiler on the target machine.\nNOTE: The readme in csources says that the branch of csources to use, should always match the branch of the main Nim repository. This is why I use -b master to make sure I take the master branch from both repositories. You can use another branch like devel but make sure you use the same on both. I was confused first because if you use --depth 1 then git will not be aware of the other branches and git branch -a will not list them.\n3. Compile first Nim compiler Link to heading Then we bootstrap a Nim compiler from the C sources using build.sh, its a generated script but its readable. It basically figures out OS and CPU and then has a big switch over the OS/CPU combinations and compiles/links the corresponding C files in the c_code directory. So the c_code/1_2 directory has the source for the 1st OS (Windows) and the 2nd CPU type (amd64), and so on. We can count 8 OSes, and Linux (OS=2) has sources for 7 different CPUs.\nWhen this is done we will have a binary nimrod compiler somewhere. If there is a koch.nim in the parent directory build.sh seems to decide to put the nimrod binary in ../bin/nimrod - fine!\n4. Compile the koch tool Link to heading Then we back up again, and use this first nimrod compiler to compile the koch.nim tool. \u0026ldquo;Koch\u0026rdquo; is the german word for \u0026ldquo;cook\u0026rdquo; and if we peek at the source this actually looks like logic you would often write as a shell script, but here its written in Nim and acts like a typical Makefile would do in other open source projects. This is the tool we want to use in order to perform various tasks, like the rest of the bootstrap for example.\nCompiling with nimrod is very simple, we just do nimrod c myfile.nim (c = compile, do nimrod -h for more info) so compiling koch.nim is just that simple. And it will do all the messy work for us that C/C++ people tend to hide in a Makefile - it will pull in all needed imports, compile everything needed, link it all together and spit out an executable called koch based on the name of the .nim file. Very nice!\n5. Run koch boot command Link to heading Now we have a koch tool written in Nim compiled with a slightly older Nim compiler written in Nim that we compiled from its C sources that was generated by someone else using an even older Nim compiler. Muaahaaha! But it gets even more funny, just wait. Now its time to let koch compile a shiny new Nim compiler from our sources, again using the \u0026ldquo;slightly older from C sources\u0026rdquo;-Nim compiler. Bootstrapping is fun.\nSo we run koch with the boot command, and we throw -d:release into the mix. This is an option for the compiler, and its a good option to be aware of if you are doing some test benchmarks learning Nim - because if you leave it out Nim will be MUCH slower, since the default is to include debugging stuff in the executable. Now, what does the boot command do?\nInsanity: doing the same thing over and over again and expecting different results. — Albert Einstein\nKoch is just 300 lines of code and its a fairly interesting example of a tool written in Nim doing \u0026ldquo;shell stuff\u0026rdquo;. But let\u0026rsquo;s look at the Heart Of Gold at line 155 here:\ncopyExe(findStartNimrod(), 0.thVersion) for i in 0..2: echo \u0026#34;iteration: \u0026#34;, i+1 exec i.thVersion \u0026amp; \u0026#34; c $# $# compiler\u0026#34; / \u0026#34;nimrod.nim\u0026#34; % [bootOptions, args] if sameFileContent(output, i.thVersion): copyExe(output, finalDest) echo \u0026#34;executables are equal: SUCCESS!\u0026#34; return copyExe(output, (i+1).thVersion) copyExe(output, finalDest) when not defined(windows): echo \u0026#34;[Warning] executables are still not equal\u0026#34; This is bootstrapping at its finest - I can just imagine the feeling Andreas had when this little thing finally said SUCCESS!\nLet\u0026rsquo;s take a look at the code above, first we find the \u0026ldquo;slightly older compiler from C\u0026rdquo;-compiler and copy it to 0.thVersion. What? Ah\u0026hellip; so its 0.thVersion() and that\u0026rsquo;s in Nim equal to thVersion(0), funky syntax and takes a while to get used to from other languages! It\u0026rsquo;s a procedure that produces a path like compiler/nimrod0.\nThen we loop 0, 1, 2 and for each iteration we compile the compiler using the compiler produced previously.\nFirst iteration we use nimrod0 (the slightly older one from C) to create a new compiler. If the resulting executable is binary equal to nimrod0 we copy the resulting compiler to the final destination, declare SUCCESS and return.\nOtherwise we copy the resulting compiler to nimrod1 and try again using this new one instead of the \u0026ldquo;slightly older one from C\u0026rdquo;. So now we are compiling it with \u0026ldquo;itself\u0026rdquo;, but \u0026ldquo;itself\u0026rdquo; was still built by the old compiler so\u0026hellip; who knows if it will work?! If that also fails the binary comparison test - then we try one last time. This time we are using nimrod2 built by nimrod1 that was built by nimrod0 (you guessed it, the old one from C).\nIf it still fails we decide that, ok\u0026hellip; whatever! \u0026hellip;and copy it to the final destination anyway, and we warn the user. Unless we are on Windows of course - those guys aren\u0026rsquo;t that picky! Just kidding, there is probably some reason for Windows being treated differently.\n6. Tada! Link to heading We got ourselves a Nim compiler - about 2Mb executable on my Linux box. Coffee. Strong.\nInstallation Link to heading Its sitting there in bin/nimrod, and we can use it and all, but perhaps we would like to install it into say /usr/local/bin or something. Again, koch to the rescue:\nsudo ./koch install /usr/local/bin\nThe install command first compiles and runs the niminst tool (see tools/niminst/niminst.nim) that in turn creates an install.sh and deinstall.sh script (for Unix/Linux that is) and then runs the install.sh script to actually copy the files to the proper places.\nIf we peek in install.sh we note that it typically puts some config files in /etc/nimrod, the binary compiler in /usr/local/bin (if that is what you chose), the standard library files in /usr/local/lib/nimrod and doc \u0026amp; data in /usr/local/share/nimrod. Worth noting is that library files are installed in source form - yay! Personally I like that.\nFinally it should be said that most core Nim developers don\u0026rsquo;t install Nim at all, they just point their PATH to the bin directory in the github clone. Nothing more needed, and that way its easier to juggle multiple Nims, each in its own directory. Simple and neat, we like it!\nAnd thus ends this little article, happy Nimming!\n"},{"title":"Cog vs LuaJIT2","permalink":"https://goran.krampe.se/2014/10/13/cog-vs-luajit/","summary":"\u003cp\u003eIn the open source Smalltalk community we have a \u003cstrong\u003epretty fast\u003c/strong\u003e VM these days - its called \u003ca href=\"http://www.mirandabanda.org/cog/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eCog\u003c/a\u003e\n and is written by the highly gifted and experienced \u003ca href=\"http://www.mirandabanda.org/cogblog/microbio/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eEliot Miranda\u003c/a\u003e\n who also happens to be a really nice guy! Cog is fast and its also still improving with some more developers joining recently.\u003c/p\u003e\n\u003cp\u003eAnother \u003cstrong\u003every fast\u003c/strong\u003e VM is \u003ca href=\"http://luajit.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eLuaJIT2\u003c/a\u003e\n for the \u003ca href=\"http://www.lua.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eLua\u003c/a\u003e\n language (version 5.1), also written by a single individual with extraordinary programming talent - Mike Pall. LuaJIT2 is often mentioned as the \u003cstrong\u003efastest dynamically typed language\u003c/strong\u003e (or VM) and even though Lua is similar to Smalltalk (well, its actually very similar to Javascript) its also clearly a different beast with other characteristics. If you start looking at the world of game development - then Lua appears \u003cstrong\u003eeverywhere\u003c/strong\u003e.\u003c/p\u003e","content":"In the open source Smalltalk community we have a pretty fast VM these days - its called Cog and is written by the highly gifted and experienced Eliot Miranda who also happens to be a really nice guy! Cog is fast and its also still improving with some more developers joining recently.\nAnother very fast VM is LuaJIT2 for the Lua language (version 5.1), also written by a single individual with extraordinary programming talent - Mike Pall. LuaJIT2 is often mentioned as the fastest dynamically typed language (or VM) and even though Lua is similar to Smalltalk (well, its actually very similar to Javascript) its also clearly a different beast with other characteristics. If you start looking at the world of game development - then Lua appears everywhere.\nI am a language lover but I admit to having only glanced at Lua earlier and wrongfully dismissed it in the category of \u0026ldquo;less capable and quirky languages\u0026rdquo;. Now that I have looked closer I realize its a similar \u0026ldquo;hidden gem\u0026rdquo; as Smalltalk is! And just as Smalltalk was given a boost of interest when Ruby hit the scene - I guess Lua gets an influx now with the Javascript craze. And the gaming world keeps infusing it with fresh code.\nLies and, well basically just lies\u0026hellip; Link to heading In Squeak Smalltalk we have this silly little benchmark called tinyBenchmarks. It\u0026rsquo;s not for benchmarking. No, let me repeat that - it really is not.\nBut hey, let\u0026rsquo;s just ignore that for a second. :) And oh, comparing Lua vs Smalltalk - speed is only a tiny piece of the picture - there are other much more interesting characteristics of these two eco systems that would affect any kind of \u0026ldquo;choice\u0026rdquo;:\nSmalltalk implementations typically have live reflective rich IDEs, and excel at complex domain models and interactive explorative development. And very clean late bound OO. Not so good at \u0026ldquo;playing well with others\u0026rdquo; though. Lua, and especially LuaJIT, is extremely good at playing with others - and specifically the C/C++ eco system. As a more traditional scripting language you have more choices in IDEs and SCM tools etc, but it is not as interactive and exploring as Smalltalk and is not focused at OO specifically, although it can do it pretty good. It does however have several good IDEs, but hardly anything matching a Smalltalk IDE. So Smalltalk excels in interactive development - but you are often limited in integration options\u0026hellip; while Lua excels as a dynamic language thriving as a catalyst in the C and C++ eco system.\nThese languages and their tools were simply born from two very different sets of goals. And Lua is also different from say Python, since Lua in contrast was designed as a minimal language (in many ways like Smalltalk was) and a language meant for embedding in a C/C++ application (almost no batteries included). This carves out a fairly unique niche for Lua.\nOk, so back to tinyBenchmarks. It consists of two small snippets of code, one measures \u0026ldquo;bytecode speed\u0026rdquo; by counting primes in a few nested loops and another is a recursive function similar to Fibonacci that just counts the number of recursive calls. Ok, so\u0026hellip; latest Cog (binary VM.r3000) vs latest LuaJIT2 (2.1.0-alpha), here follows the Lua code I whipped up. I tried basically three different variants on the Fibonacci recursion to see how much penalty an OO design would give.\nlocal class = require(\u0026#34;classy\u0026#34;) -- First here is how you would do it in proper Lua, just a recursive function local function benchFib(fib) if fib \u0026lt; 2 then return 1 end return 1 + benchFib(fib-1) + benchFib(fib-2) end -- Or using a metatable for a bit more manual OO style local Bench = {} Bench.__index = Bench -- A constructor function Bench.new() local bench = {} setmetatable(bench, Bench) return bench end -- And a method in it function Bench:benchFib(fib) if fib \u0026lt; 2 then return 1 end return self:benchFib(fib-1) + self:benchFib(fib-2) + 1 end -- A variant using the \u0026#34;Classy\u0026#34; OO lib. Another popular is called \u0026#34;MiddleClass\u0026#34; local Benchy = class(\u0026#34;Benchy\u0026#34;) -- And a method in it function Benchy:benchFib(fib) if fib \u0026lt; 2 then return 1 end return self:benchFib(fib-1) + self:benchFib(fib-2) + 1 end -- And this is the bytecode benchmark translated just as it says in Squeak local function benchmark(n) local size = 8190 local count = 0 for j=1,n do count = 0 local flags = {} for q=1,size do flags[q] = true end for i=1,size do if flags[i] then local prime = i+1 local k = i + prime while k \u0026lt;= size do flags[k] = false k = k + prime end count = count + 1 end end end return count end -- Return seconds to run fn local function timeToRun(fn) local start = os.clock() fn() return os.clock() - start end t1 = timeToRun(function() benchmark(100000) end) t2 = timeToRun(function() benchFib(47) end) t3 = timeToRun(function() Bench.new():benchFib(47) end) t4 = timeToRun(function() Benchy():benchFib(47) end) print(t1 .. \u0026#39; bytecode secs\u0026#39;) print(t2 .. \u0026#39; benchFib send secs (normal Lua)\u0026#39;) print(t3 .. \u0026#39; Bench send secs (OO Lua)\u0026#39;) print(t4 .. \u0026#39; Benchy send secs (OO Lua Classy)\u0026#39;) And the Smalltalk code would be:\nTranscript show: ([100000 benchmark] timeToRun / 1000.0) asString, \u0026#39; bytecode secs\u0026#39;;cr. Transcript show: ([47 benchFib] timeToRun / 1000.0) asString, \u0026#39; send secs\u0026#39;;cr@ I picked 100000 and 47 to get fairly long running times, so LuaJIT:\n10.248302 bytecode secs 26.765077 benchFib send secs (normal Lua) 70.418739 Bench send secs (OO Lua) 71.003568 Benchy send secs (OO Lua Classy) \u0026hellip;and Cog:\n49.606 bytecode secs 58.224 send secs So LuaJIT2 is about 4x faster on bytecode speed and 2x faster on recursive calls.\nBut wait, lots of things to note here:\nThese are two trivial benchmarks meant to detect really bad regressions in VM code, not benchmarking. The above. Read it again. A recursive function call in Lua is not the same thing as a message send with full OO lookup in Cog. If we look at Bench and Benchy we see that 2x factor vanish! Integer math is clearly different in Lua vs Smalltalk. Lua does doubles only, Smalltalk has a full math system falling back to \u0026ldquo;big ints\u0026rdquo; when needed! Using Classy was the same speed as manual metatable approach. So in Lua you would definitely use such a lib instead of manual OO, much easier and with nice features. And oh, both grabbed a single core by the throat doing this - Cog even managed to squeeze out 104%! :) Conclusion Link to heading There is no real conclusion from the silly benchmark - it was just a fun exercise! I already knew Cog is pretty darn fast and LuaJIT is the King of the Hill - it even beats V8 regularly. Cog on the other hand is executing a much more refined and advanced language and object system, you really do need to keep that in mind here.\nBut I hope that especially Smalltalkers might get intrigued by this article and find Lua interesting. To me its much nicer than Javascript. Its also the first time in many years that I have found a language that actually can keep my interest for a longer period - despite me constantly comparing it with my beloved Smalltalk.\nPython could never keep me interested, although I did try - but it kept turning me off, so unclean, lots of different mechanisms, too complicated. Same story with Ruby, too messy, no elegance and a community drug crazed with nifty tricks\u0026hellip; IMHO.\nBut Lua has that smallness that Smalltalk has, it feels \u0026ldquo;designed\u0026rdquo;. It has strong abstractions that it carries through all the way. In short it doesn\u0026rsquo;t turn me off. And then, a lot more in this eco system is pure candy. LuaJIT2 has awesome speed. Very powerful interoperability with C and C++, in fact, the LuaJIT FFI can call C libraries as fast as C can! Tons of good libraries and tools. Very strong on mobile development. Many interesting projects like TurboLua, Tarantool, OpenResty, Lapis, Metalua etc etc.\nAlways nice to realize that there still is stuff out there that can attract an old Smalltalk dog\u0026hellip; :)\n"},{"title":"Here Comes Nim!","permalink":"https://goran.krampe.se/2014/10/13/here-comes-nim/","summary":"\u003cp\u003eI just posted an article comparing some silly benchmarks between Cog Smalltalk and LuaJIT2. Now\u0026hellip; let\u0026rsquo;s take a look at one of the latest \u0026ldquo;Cool Kids\u0026rdquo; on the language front, Nimrod - or as it has been renamed - \u003ca href=\"http://nim-lang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNim\u003c/a\u003e\n.\u003c/p\u003e","content":"I just posted an article comparing some silly benchmarks between Cog Smalltalk and LuaJIT2. Now\u0026hellip; let\u0026rsquo;s take a look at one of the latest \u0026ldquo;Cool Kids\u0026rdquo; on the language front, Nimrod - or as it has been renamed - Nim .\nSo I love programming languages. But generally I have preferred dynamically typed languages because I have felt that the static type systems that we have suffered with for the last \u0026hellip; 25 years or so has basically been completely awful. Perhaps not in implementation performance, but definitely in developer productivity and enabling good quality code.\nWorking in say Smalltalk has been like roaring free in the skies instead of crawling in the mud with C++, well, you get my point. I still recall one of the first 30 line \u0026ldquo;programs\u0026rdquo; I wrote in Smalltalk, just quickly jotted it down - and it ran perfectly at the first try. I attributed that to the concise language and \u0026ldquo;noise free\u0026rdquo; code (no static type noise!). My first stumblings in C++? Ha! Its not even funny.\nBut I have never been against static type information per se - I mean, its just a question of what we need to tell the compiler\u0026hellip; so if we can have a type system that can reason around my code at compile time without bogging me down in endless typing and convoluted code that is hard to change and refactor and hard to read and hard to write\u0026hellip; argh! Then yes, by all means.\nMany new statically typed languages have started incorporating type inference. I haven\u0026rsquo;t really worked with them, Haskell is perhaps one of the best known. Dart is a dynamically typed language but instead opted to adding mechanisms for static type annotation in order to help on the tooling front, a clever idea IMHO.\nRust, Go and\u0026hellip; Nim! Link to heading In another article I wrote about Rust and Go (and more) - two new, popular and very interesting statically typed languages. But I admit that I totally missed Nim! Previously known as Nimrod, ehrm. And yes, Nim does have type inference, although to a balanced extent.\nJust like LuaJIT2 has been a \u0026ldquo;Tour de Force\u0026rdquo; of a single author, so has Nim - and that is interesting in itself. I would say it has been a pattern over the years with most successful open source languages.\nOk\u0026hellip; so enough chit chatting, let\u0026rsquo;s look at that silly benchmark I played with earlier - in Gang Nim Style:\n# Import times for time measurements and future for some upcoming features (naked lambdas) import times, future # Just a recursive function, the astute reader notes that we declare a return type of int64 proc benchFib(fib) :int64 = if fib \u0026lt; 2: return 1 else: return 1 + benchFib(fib-1) + benchFib(fib-2) # Trivial helper to measure time, discard is used to show we ignore the return value proc timeToRun(bench) :float = var start = epochTime() discard bench() epochTime() - start # And this is the bytecode benchmark translated from Squeak proc benchmark(n) :int = const size = 8190 var flags: array[1..size, bool] for j in 1..n: result = 0 # Clear all to true for q in 1..size: flags[q] = true for i in 1..size: if flags[i]: let prime = i + 1 var k = i + prime while k \u0026lt;= size: flags[k] = false inc(k, prime) inc(result) # And echo the time to run these two, note the naked lambda syntax \u0026#34;() =\u0026gt; code\u0026#34; # The \u0026#34;\u0026amp;\u0026#34; is string concatenation. The $ before timeToRun is \u0026#34;toString\u0026#34; echo($timeToRun(() =\u0026gt; benchmark(100000)) \u0026amp; \u0026#34; bytecode secs\u0026#34;) echo($timeToRun(() =\u0026gt; benchFib(47)) \u0026amp; \u0026#34; sends secs\u0026#34;) Whoa! Look at that code! I mean\u0026hellip; it looks like Python-something! And not much static type noise going on, in fact there are only 4 places where I specify types - the three return types of the three procs, and I also specify that the array has bools in it. That\u0026rsquo;s it.\nIf you recall the numbers from LuaJIT2:\n10.248302 bytecode secs 26.765077 send secs \u0026hellip;and Cog:\n49.606 bytecode secs 58.224 send secs \u0026hellip;then Nim mops the floor with them:\n2.6 bytecode secs 7.6 sends secs So Nim is about 4x faster on bytecode speed and 3x faster on recursive calls compared to LuaJIT2. And about 20x faster on bytecode speed and 8x faster on recursive calls compared to Cog.\nA few things of note:\nThe Nim code is just as small and readable as the Lua and Smalltalk code. The brute speed comes from shoulders of giants, GCC. But it also means that the generated code is fairly C-friendly, which is fascinating given the depth of this language. I used a few extra features; const for the size, let for prime (non assignable var), inc() for incrementing variables - but all these didn\u0026rsquo;t affect the numbers much, it was just fun to try to make it more Nimiomatic. The above little snippet compiles in 0.2 seconds to a 67kb executable on Linux using the short command \u0026ldquo;nimrod c -d:release test.nim\u0026rdquo;. Nice! Conclusion Link to heading I wrote this as a teaser - Nim is actually a brutally darn cool language. Lots of people seem to prefer it over Rust - and it has a \u0026ldquo;pragmatic\u0026rdquo; soul - Rust on the other hand is very focused on safety, safety, safety. Nimrod is more focused on developer productivity. And it has a lot of nice stuff:\nWritten all in itself, clean and nice bootstrap. Compiles via C (or C++/ObjC) which gives it very good performance, platform independence and integration with C/C++/ObjC etc. Has a very neat modules system Has lots of really, really interesting language features. Sure, a bit featuritis perhaps - but I am not judging just yet. \u0026hellip;and well, I just can\u0026rsquo;t go through it all here! Its too much! I would say that if you are thinking of perhaps taking a peek at the \u0026ldquo;Dark Side\u0026rdquo; (static typing) - then this is it. I think Nim will make you smile in more ways than one.\n"},{"title":"ESUG in Annecy Day 4","permalink":"https://goran.krampe.se/2013/09/12/esug-in-annecy-day-4/","summary":"\u003cp\u003eIt starts off with Cincom, Arden Thomas presenting their roadmap. He had a slide mentioning Jules Verne and I must ask him if he is aware of the influence from the books of Jules Verne - as Dan has explained, the ballon and the island in the \u003ca href=\"http://st-www.cs.illinois.edu/Graphics/bytebloon.jpg\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eclassic Smalltalk logo\u003c/a\u003e\n comes \u003ca href=\"http://wiki.squeak.org/squeak/3459\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003efrom the Mysterious Island book\u003c/a\u003e\n.\u003c/p\u003e","content":"It starts off with Cincom, Arden Thomas presenting their roadmap. He had a slide mentioning Jules Verne and I must ask him if he is aware of the influence from the books of Jules Verne - as Dan has explained, the ballon and the island in the classic Smalltalk logo comes from the Mysterious Island book .\nMist Link to heading Martin McClure enters the stage, this should be fun. Ah, now we are back to the metal! So Mist looks like a promising new really low level Smalltalkish language. So no VM, just Mist compiling to Fog compiling to machine code. A non moving memory scheme influenced by the memory allocator in the Linux kernel (I think he said), that simplifies TONS of things. No object header, things like identityHash or pointer to class is just instance variables. Slick. And the addition of tail call eliminiation, is that a first in a Smalltalk implementation? Probably not, but still a very nice thing.\nMist is of course a \u0026ldquo;low level hacking bliss\u0026rdquo; project, it can\u0026rsquo;t really do anything yet :). But life is not always work, sometimes its just for fun. And yes, Martin had an episode of Forth earlier in his programming life, and the Forth community has a lot of track record in \u0026ldquo;going down to the metal\u0026rdquo;.\nMongodb and Voyage Link to heading Nico and Esteban did a tutorial on MongoDB and Voyage and I was there but not really following it. I am personally really interested in NoSQL databases but I have always hesitated about MongoDb so while I like to see how things work I will not use it myself. I am much more interested in other alternatives :)\n\u0026hellip;more to come\u0026hellip;\n"},{"title":"ESUG in Annecy Day 3","permalink":"https://goran.krampe.se/2013/09/11/esug-in-annecy-day-3/","summary":"\u003cp\u003eDay three blurred a bit for me - lots of mingling and hacking intermixed with some nice presentations, but I missed quite a lot, I admit, like the presentation on new native UI stuff in VisualWorks and the \u003ca href=\"https://github.com/dalehenrich/tode\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003etODE\u003c/a\u003e\n stuff from Dale Henrichs.\u003c/p\u003e","content":"Day three blurred a bit for me - lots of mingling and hacking intermixed with some nice presentations, but I missed quite a lot, I admit, like the presentation on new native UI stuff in VisualWorks and the tODE stuff from Dale Henrichs.\nI sat around messing with various things (mostly scratching my head on VM building issues) next to Nicolas who was fiddling with the Amber compiler adding some support mechanisms in the generated code for his debugger to play nice - this is probably something we will see tomorrow in his presentation on Amber.\n3DICC and Terf Link to heading I did also get a chance, just when the day ended, to do a quick presentation of 3DICC and Terf on a 10 minute slot. I swirled through about 18 slides but I think the pictures looked interesting, and I did a really quick run around inside Terf.\nUnfortunately (argh!) the connection went down (probably the silly unpredictable timeout that has been hitting people the whole week) but I think it showed enough for people to find it interesting. A few people mistakenly thought the customer case presentations were examples of possible use cases - and not actual true customer cases - but I did stress these were quick presentations and screenshots from real deployments.\nSocial event Link to heading My presentation lead to several interesting discussions later on the social event during the evening. And yes, the social event was neat, right by the lake (no rain) with good food and wine - and live music, nice!\nNicolas Petton won silver in the Smalltalk Innovation Technology Awards for Amber (Guillermo Pollito took the gold with Oz and Yannick Laval took the bronze with Phratch), but I must admit I think Nicolas deserved gold, but I am partial to the project of course! :)\nCongratulations to all three!\nI had several fun and interesting discussions with people like Igor Stasenko, Martin McClure, Dan Ware, Benjamin Van Ryseghem, Dale Henrichs, Norbert Hartl and many, many more.\n"},{"title":"ESUG in Annecy Day 2","permalink":"https://goran.krampe.se/2013/09/10/esug-in-annecy-day-2/","summary":"\u003cp\u003eAnother day in \u003ca href=\"http://www.iae.univ-savoie.fr\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eIAE Universite Savoie Mont-Blanc\u003c/a\u003e\n in Annecy.\u003c/p\u003e\n\u003cp\u003eOnly writing about stuff I attended :)\u003c/p\u003e","content":"Another day in IAE Universite Savoie Mont-Blanc in Annecy.\nOnly writing about stuff I attended :)\nGemStone/64 Update Link to heading A really good presentation from GemTalk! They are presenting a lot of customer cases in a way I have never seen before. Perhaps I just missed this earlier years on various conferences - but this was refreshing. This is what I want to hear. I can\u0026rsquo;t help thinking this may be due to the fact that GemTalk now again stands on its own? Or perhaps not, but it was a very nice open presentation.\nNativeBoost tutorial Link to heading So Damien Pollet was running a tutorial on NativeBoost and it was good, but I personally ended up distracted since I got stuck on some odd error - apparently I was the only one (!) using Linux. Odd. I am a liiittle bit worried about all these Smalltalkers moving to the Mac. Come on guys! But NativeBoost rocks and is a true enabler for lots of interesting stuff. In fact, I was contemplating making a plugin for a specific task and now I am toying with the thought of perhaps using NativeBoost instead. I did try it earlier, so I know how it works, and these days it is probably better documented.\nBuilding a Pharo VM Link to heading After that it was lunch and the schedule didn\u0026rsquo;t look that amazing so I ended up hanging around with Igor for a while, discussing this-and-that and finishing it off with a quick guide on how to check out and build the Pharo VM from github. It\u0026rsquo;s nice and much easier than before - the only thing biting us was hunting down the correct libraries - and yeah, as i386 and not the default x86_64 of course ;)\nSo reflecting a bit on that - building the VM has never been easier. In the end the steps were:\nClone it from github. Run a shell script that automatically pulls down a VM binary and image that can generate sources. Fire up the generator image and run a single doit that is in front of you. Run the final build.sh script that basically run cmake and then make. \u0026hellip;and then spend a few minutes hunting down libraries missing (but I think cmake on the Mac does it for you) Now, everyone who has built VMs before knows that the above procedure is a dream. And the best thing is that it is all properly versioned/contained inside that git repository. No hunting down version this of that and version that of this.\nEvening Link to heading So I spent most of the rest of the day talking to Igor and then we joined up with Igor\u0026rsquo;s wife Lucy and Hilaire Fernandes and went to a very nice restaurant in old town, Alpine I think it was called. Thank you guys for a great evening!\n"},{"title":"ESUG in Annecy Day 1","permalink":"https://goran.krampe.se/2013/09/09/esug-in-annecy-day-1/","summary":"\u003cp\u003eHere we go! Time for a week of Smalltalking fun in \u003ca href=\"http://www.iae.univ-savoie.fr\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eIAE Universite Savoie Mont-Blanc\u003c/a\u003e\n in Annecy.\u003c/p\u003e\n\u003cp\u003eWhile \u003ca href=\"esug.org/wiki/pier/Conferences/2013\" \u003eESUG\u003c/a\u003e\n this year is not super big, I think \u003cstrong\u003earound 110 people\u003c/strong\u003e or so, there were still quite a few arms raised when checking how many were here for the first time. The organisation seems impeccable, as always - thank you Stéphane Ducasse, Herve Verjus, Laurent Laffont and of course all volunteers!\u003c/p\u003e\n\u003cp\u003eEnough chit-chat, let\u0026rsquo;s get on with the talks\u0026hellip;\u003c/p\u003e","content":"Here we go! Time for a week of Smalltalking fun in IAE Universite Savoie Mont-Blanc in Annecy.\nWhile ESUG this year is not super big, I think around 110 people or so, there were still quite a few arms raised when checking how many were here for the first time. The organisation seems impeccable, as always - thank you Stéphane Ducasse, Herve Verjus, Laurent Laffont and of course all volunteers!\nEnough chit-chat, let\u0026rsquo;s get on with the talks\u0026hellip;\nVA Smalltalk Product Update and Roadmap Link to heading We started off with news from Instantiations with John O\u0026rsquo;Keefe. Instantiations is evidently growing and has been able to employ more engineers, nice! And tada, a new release, v8.6 ! And the most notable change seems to be the new Scintilla based text editor. Also a lot of small tweaks to the debugger and other tools.\nSeaside and GLORP are two very important open source tools for companies that want to build web apps in VAST. Seaside obviously, being the mature (IMHO outdated by now, but still important given its maturity) web framework of the Smalltalk world. And GLORP for any larger company where data of course lives in some RDB. Upcoming planned features include 64 bit support and improved GC, and a lot more.\nAlthough I am not using VAST (though I did back in the 1990s for some projects) it is very nice to hear its still live and kicking. Note though that these tools are not cheap - they are very mature development tools aimed for large enterprise customers. On the other hand they have special offers for open source developers and academia.\nWhat I find interesting is how these companies handle the furious evolving industry, do they know how to play well with open source? Do they understand how to attract new customers? Instantiations seems to be doing well but I can\u0026rsquo;t stop wondering if they are attracting new customers or living on their old base. In any case I wish them all the best.\nMVC Revival on the Web Link to heading Next up was Janko Mivsek going through MVC. The history is quite interesting, going all the way back to 1978/79 when Trygve Reenskaug created this pattern when he visited PARC. You can google all this and if you don\u0026rsquo;t know the history I think it is worth reading about it because MVC is such an \u0026ldquo;abused\u0026rdquo; term these days.\nPretty soon Janko moved over to present day and the onslaught of javascript frameworks for \u0026ldquo;MVC\u0026rdquo;. Backbone.js, AngularJS, KnockoutJS, Ember.js blablabla\u0026hellip; :) Personally I haven\u0026rsquo;t looked at these, but perhaps I should! And of course, how does Amber fit into these ideas\u0026hellip;\nBeach Parasol Link to heading Web testing. So\u0026hellip; how to use Selenium WebDriver (instead of the older Remote Control?). A quite interesting presentation on how to do web testing of Seaside (or other apps) using this from within Smalltalk.\n\u0026hellip;and then my attention kind of drifted, sorry guys. The presentation Towards a Smalltalk VM for the 21st Century was interesting, Boris showed how to use a low level full system simulation like Simics to put a breakpoint into the VM machine code and then go in and inspect registers and memory when it is stopped. Another very interesting capability is to \u0026ldquo;record\u0026rdquo; execution and then go back and replay to find critical timing bugs for example - you know, those \u0026ldquo;Heisenbugs\u0026rdquo; that hide themselves when you step in the debugger.\nThe evening moved onto the Innovation Technology Awards where we had the chance to see 10 (or so?) projects being presented by the authors while the rest of us drank beer and wine. :) Really nice and IMHO the clear winner should be Amber . Ok, so I may be a bit partial, but Amber is such a true tour de force in crafting a whole new Smalltalk including a really nice modern compiler toolchain, slick and fast IDE running inside your browser and now even a stepping debugger through the brilliant move to implement an Amber AST interpreter in Amber, thus enabling interactive stepping of Amber code.\nEvening Link to heading Bus downtown and long interesting talks into the warm night. :)\nOver and out.\n"},{"title":"New Languages After 2000","permalink":"https://goran.krampe.se/2013/09/07/new-languages-after-2000/","summary":"\u003cp\u003eI am sitting in a gate on an airport waiting to go to \u003ca href=\"http://www.esug.org/wiki/pier/Conferences/2013\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eESUG\u003c/a\u003e\n so I felt I should finally get this article out the door. In a presentation earlier this year I asked what has happened in the programming language area since year 2000? \u003cem\u003eNot much\u003c/em\u003e I felt and I couldn\u0026rsquo;t really name any interesting new language when thinking about it. But then I decided to look more closely and I can conclude I was at least partly wrong :)\u003c/p\u003e\n\u003cp\u003eSo prepare for a \u003cstrong\u003elong\u003c/strong\u003e (too long) article digging through a whole bunch of languages trying to come up with the answer - \u003cem\u003eHave any interesting programming languages appeared since year 2000?\u003c/em\u003e\u003c/p\u003e\n\u003cp\u003e(And at the end, how is the Smalltalk community doing?)\u003c/p\u003e","content":"I am sitting in a gate on an airport waiting to go to ESUG so I felt I should finally get this article out the door. In a presentation earlier this year I asked what has happened in the programming language area since year 2000? Not much I felt and I couldn\u0026rsquo;t really name any interesting new language when thinking about it. But then I decided to look more closely and I can conclude I was at least partly wrong :)\nSo prepare for a long (too long) article digging through a whole bunch of languages trying to come up with the answer - Have any interesting programming languages appeared since year 2000?\n(And at the end, how is the Smalltalk community doing?)\nGoogling wikipedia and more gave me this list of languages (and yes, you may point out more in the comments I am sure) that seem to be \u0026ldquo;somewhat successful\u0026rdquo; and were born after 2000:\n2000: D, C# 2002: Io 2003: Scala, Factor, Nemerle 2004: Boo, Groovy 2005: F# 2006: Cobra, Cyclone 2007: Vala, Fortress, Fantom, Clojure, Nu 2008: Pure 2009: Go 2010: Rust, Gosu 2011: Dart, TypeScript, Clay 2012: Julia, Ceylon Here comes the broom Link to heading I have excluded several already due to different factors that indicate to me that they will likely not reach any kind of critical mass of adoption. And let\u0026rsquo;s get the broom out again and prune this list so that it includes the ones that I think may be worth keeping an eye on. Please remember this is my personal take on these languages driven by my personal taste and experience.\n[C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language) is legacy by now and well, not really interesting to me. Yes, I have coded a fair bit in both C# and Java and both will be around for a long time - but I really do consider them boring and frustrating :)\nD is impressive by all means, technically a contender with C++ - but I do not think it offers enough differences to dethrone C++ from its niche and it is (just like C++) a complex language and I think that a successful new language should not have to be that complex and it definitely needs to bring something new to the table and not just be a \u0026ldquo;cleaner C++\u0026rdquo;.\nIo is a small very nice language, but not going anywhere - just wanted to mention it :)\nFactor is another real LSD trip, immensively impressive but being a concatenative (thus fairly cryptic to most of us - although Forth is way cool) language I consider it doomed to be a niche player, nothing wrong with being that of course! Can be a source of inspiration.\nNemerle as well as Boo and Groovy suffer from the \u0026ldquo;Why not just use Java/C# then?\u0026rdquo; being languages focused on the CLR and JVM platforms respectively with seemingly too little momentum behind them compared to other languages on these two runtime platforms. I don\u0026rsquo;t think they stand much of a chance in the longer run. And yes, they are different - Nemerle is functional and Groovy is dynamically typed for example - but still, my impression is that they are being dwarfed. F# and Clojure share this problem - and being functional also narrows down the audience. Although I agree that Clojure has seen lots of hype.\nCobra seems to be a kitchen sink language built ontop of the CLR runtime, and while touting a fairly massive feature list it didn\u0026rsquo;t tickle me. Languages that try to implement as many features as possible is not up my alley. Cyclone seems to be a \u0026ldquo;safe C\u0026rdquo; and while possibly useful I don\u0026rsquo;t think that punchline will attract enough people.\nVala is a niche Gnome language which is statically typed, depends on GObject and Glib, uses reference counting and compiles through C. An extremely pragmatic approach and clearly a step up for C developers working in Gnome, not interesting enough though.\n[Fortress](http://en.wikipedia.org/wiki/Fortress_(programming_language) is officially dead, so not really more to say about it, it did have some cool stuff in it, but it was also aimed squarely at the mathematical community turning it into a niche language.\nFantom seems to be an attempt to harmonize Java and C# and cleaning up a lot of things, IMHO doomed also since it just isn\u0026rsquo;t different enough to gain any reasonable following and I also think those two communities \u0026ldquo;don\u0026rsquo;t mix\u0026rdquo; that much. On paper I can agree with lots of its design decisions, but where is the community? Where is the momentum? Can\u0026rsquo;t see it.\nThe Nu language is a Ruby/Lisp language built ontop of Objective-C\u0026hellip; not interesting to me, too much niche (says the Smalltalker).\nPure is functional, and with a focus on LLVM as the backend it might get some followers in the functional crowd, but again, sorry, I think pure functional languages still fight an uphill battle - and personally I am not comfortable in them. ;)\nGosu is a Scala competitor that is simpler in several ways (which is probably a plus for many), less mature and less intrusive in how it modifies Java. But still a \u0026ldquo;cleaned up Java\u0026rdquo;. Ceylon is RedHat\u0026rsquo;s answer to \u0026ldquo;the next Java\u0026rdquo; and also tries to be simpler than Scala . All these three turn me off since they are JVM languages (ok, so Ceylon can also run on Javascript\u0026hellip;). I am sorry, it\u0026rsquo;s not rational - but there it is.\nBut that doesn\u0026rsquo;t mean you shouldn\u0026rsquo;t keep an eye on them - I think one of these may very well end up being the long term successor of Java that Java sorely needs, although it will take a few years (or decades). If these languages make the lives a tad better for the hoards of Java developers - then that is indeed a good thing :)\nThis boiled the list down to Go, Rust, Clay, Dart, TypeScript and Julia.\nTypeScript is also a turnoff for me, simply because it isn\u0026rsquo;t ambitious enough - same goes for CoffeeScript which I didn\u0026rsquo;t even bother to list, it\u0026rsquo;s just syntactic sugar. TypeScript is of course more than CoffeeScript, but being a pure superset of javascript is not making me smile. And oh, Microsoft? Ehrm. All respect to Anders Hejlsberg though, no shadow on him.\nClay is an interesting language and plays in the same \u0026ldquo;systems programming\u0026rdquo; arena as C/C++/D/Rust do - if you let me generalize a bit. So Clay is basically a C++ competitor but cleaned up and adding type inference, multiple dispatch and lambdas etc. Unfortunately I don\u0026rsquo;t think it has enough push behind it to compete with the others, the original author lost interest and well, things probably stalled. Unfortunately.\nSo what is left? Link to heading It seems the last 13 years have produced the following short list of REALLY interesting new languages with a plausible chance of becoming more than curiosities (and of course, I will be wrong on this prediction):\nGo . The Erlang inspired semi low level language from Google. Has traction, quite a bit of libraries and seems like fun and with good performance, around 1/2 of C. Not LLVM based, compiles using own compiler or GCC toolchain. Rust . The low level high performance system programming language from Mozilla with lots of new interesting concepts. Finally a C/C++ replacement? Compiles through LLVM. Beta but clearly has attention and promises of good performance, although I am not sure about the current state. Dart . The high level dynamically typed javascript killer from Google. In fact, Dart is IMHO a \u0026ldquo;Smalltalk in disguise\u0026rdquo; (not surprising given the background of several of the team members) and is the only language in this pack that is also targetting the client side of HTML5 and the server side. And yes, at least two of the languages I discarded promise the same - Ceylon and Typescript. Dart has both its own V8-ish VM and can compile to javascript. Performance using its own VM is already a bit better than javascript on V8. Julia . A high level dynamically typed multiple dispatch language with performance close to C? Extremely impressive from several points of view, also LLVM based. All these four languages are fascinating and all have some characteristics I would consider \u0026ldquo;new stuff\u0026rdquo;. So I have to retract my view that there hasn\u0026rsquo;t been any new interesting languages the last decade, that is simply not true. On the other hand, none of them has yet gained any substantial momentum.\nIt is also interesting to see that they cover different domains, with some overlap of course, but they do not really compete fully head to head. Rust wants to replace both C and C++ and can be used without a runtime just like C, it has GC but it is optional. Go has GC so for really low level things it is probably not suitable, it seems to be more of a \u0026ldquo;service level\u0026rdquo; language (kinda the same niche as NodeJS) - not what you use to build an OS or a VM with, but definitely what you can use above that level. Both Go and Rust are statically typed. Dart and Julia are dynamically typed high level languages.\nAll seem to have good performance in relation to their design choices. Three of them use LLVM as backend technology (well, ok, I did filter out all the JVM/CLR competition!) - which is a smart choice since primarily Apple has been pouring TONS of effort into that toolchain and I guess it is only a matter of time before it replaces GCC.\nGo and Dart are from Google and Rust from Mozilla so all but Julia are backed by organisations. Julia on the other hand is coming from academia. Dart is fairly obviously aimed at the web. Julia is primarily aimed at math.\nNow, let me give you my personally biased view on these four languages without actually having coded in them - yeah, I know, silly me, so take it with a huge grain of salt!\n##Go\nGo is interesting and a lot of people love parts of it and \u0026hellip; a lot don\u0026rsquo;t. The language is statically typed with a clear C syntactic inheritage. Go is not object oriented in any traditional point of view - but it has mechanisms that seem to reach more or less similar capabilities. First of all, one can associate functions with structs to create \u0026ldquo;classes\u0026rdquo;, seems fine but I do fail to see the advantage over calling them \u0026ldquo;classes\u0026rdquo; and keeping the methods declared inside? Perhaps this \u0026ldquo;structs + functions\u0026rdquo; has some subtle difference I am missing.\nThere is no inheritance but one can compose structs without naming the members, this will expose the members of that \u0026ldquo;anonymous\u0026rdquo; member on the outside of the parent struct, a sort of transparent automatic delegation. So this gives us inheritance by composition (an area I feel has been lacking in general in the OO world) - so this is clearly an interesting approach.\nAnother nice idea is how interfaces work in Go - the struct that \u0026ldquo;implements\u0026rdquo; an interface doesn\u0026rsquo;t need to say so! This is also something I have been looking for in statically typed OO languages for a long time. Of course, in dynamically typed OO languages we have this \u0026ldquo;automatically\u0026rdquo; so to speak. This decouples interfaces from the implementation and turns it into a one sided dependency. One can add interfaces implemented by \u0026ldquo;old code\u0026rdquo; etc, kind of the static equivalence of formalized duck typing.\nI do like minimalistic languages and Go is definitely trying to be small, but if we compare to other minimalisic languages like Smalltalk and Lisp - the thing that makes these languages \u0026ldquo;get away\u0026rdquo; with being small - is the fact that they have powerful meta capabilities in which to implement mechanisms in libraries instead of in the language. Smalltalk for example has an Exception model more powerful than the one in Java, and it is all created in Smalltalk without modifying the language or the VM.\nSo if you try to be minimal you need careful design - and one of the areas in Go that feels\u0026hellip; too much 1970 is the error handling model. I can sympathize with trying to find something simpler than Exceptions, but this \u0026ldquo;mix\u0026rdquo; of error mechanisms in Go feels cobbled together without true thought, and I don\u0026rsquo;t think it makes very readable code either. But don\u0026rsquo;t take my word for it - perhaps it is simply brilliant and I can\u0026rsquo;t see it.\nOnly one loop keyword and that is \u0026ldquo;for\u0026rdquo;? Ok, perhaps I can buy that. No generics in a manifest statically typed language? So they added special case generic array and hashmaps, but that only removes the casting pain for these builtin collections. Mmm, ok. All in all I hesitate regarding Go and I did find someone managing to put his finger on it:\n\u0026ldquo;So, where is Go supposed to fit? I\u0026rsquo;ll gladly acknowledge Go is a far better C, with garbage collection. But the GC makes it unacceptable for the only types of problems I\u0026rsquo;d ever consider using C for. And if I\u0026rsquo;m willing to put up with a GC, I\u0026rsquo;d always prefer Java/Scala/Python/Lisp/Haskell over Go for any problem I can think of.\u0026rdquo;\nAt the same time Go seems to be attracting developers from the Ruby/Python camp that are looking for higher performance and better support for concurrency - instead of people from the Java camp sick of complexity, as some might have predicted.\nIn summary, performance seems pretty good and I like the \u0026ldquo;inheritance by composition\u0026rdquo; and the \u0026ldquo;duck type interfaces\u0026rdquo; - clearly an interesting language, but for me Go doesn\u0026rsquo;t find a proper niche.\n28 committers on google code, most from Google. And a really ugly homepage :)\nRust Link to heading Let\u0026rsquo;s get our hands even dirtier with some rust. This is hard core stuff and reading the tutorial while putting on your \u0026ldquo;close to the metal\u0026rdquo; hat it starts out really good:\nType inference! Yes. A must have in a modern statically typed language I think. Almost everything is an expression. Very nice! Just like in Smalltalk. There is a nil type with a single value - (). Nice. Syntax? Odd, but ok. There is a bool type with proper literals true and false. The way it should be of course. There is a char type which is a 4 byte unicode point. Nice! As a Smalltalker it is obvious, but still good. Casting is done using \u0026lt;expression\u0026gt; as \u0026lt;type\u0026gt;. Also fine, readable. Regular operators etc like in C, fine, can live with that - we are on the metal after all. Syntax extensions with a clear marker (!) and use proper/clean AST macros. Ok, this is\u0026hellip; advanced stuff and somewhere here the language starts slipping into the darker land of complexity. But let\u0026rsquo;s give them the benefit of the doubt. Only bool works in conditionals. Thank you, thank you. C and Javascript really botched booleans so I am glad Rust is sensible. Has a match statement which is a switch statement on steroids, seems very powerful bordering on over engineered. This is begging for abuse. And then we get to the core of Rust, the three different kinds of memory and how to work with references to them. In theory, cool. In practice? Not sure. Very quickly the code starts looking like \u0026hellip; Perl. And that is NOT a good thing :). Reading the mailing list a bit shows \u0026ldquo;where\u0026rdquo; the language is currently and yes, it is early, but moving fast and participation is heating up. If you try to follow the discussions on the mailinglist you quickly realize that Rust is not a simple language - there are a lot of nuances here in the joint complexity created by mutability, generics, three kinds of pointers and just to make it a true headshot - pointer lifetimes. One thing that I did notice is that it is already quite performant at version 0.6 .\nIf all these features don\u0026rsquo;t make your head spin, well, then perhaps you are a seasoned C++ programmer - nothing scares them. :) It scares me though. The problem is - each concept on its own may seem logical and reasonable. But its the mix that makes it go \u0026ldquo;ouch\u0026rdquo;. But the authors of Rust are very aware of this \u0026ldquo;cognitive burden\u0026rdquo;, the question is - can they do something about it? And do they want to? I am a reasonably experienced developer but I want to use my brain cells for the domain and not for fighting the compiler.\nThis interesting quote positions Rust vs Go etc:\n\u0026ldquo;Rust is basically ML + C\u0026rsquo;s lovechild. Sophisticated type inference, mostly pure variables, pattern matching lambda functions, a few other FP goodies. But it\u0026rsquo;s also a fairly clean imperative language if you care to use it like that. Generics, mutable variables, {}; syntax, pointers, etc. Also, more fundamentally, I see D, OCaml, and Rust as occupying a \u0026ldquo;let\u0026rsquo;s be clean\u0026rdquo; kind of space. I see Go as occupying a \u0026ldquo;let\u0026rsquo;s be scruffy\u0026rdquo; space; not really pushing the language state of the art, focused on industrial work; it\u0026rsquo;s like a type-safer \u0026amp; compiled python, afaict. It doesn\u0026rsquo;t really strive to push the state of the art, it seeks to solidify certain well-known taken ground in programming language design, and to be really focused on that.\u0026rdquo;\nAnd from Reddit, let me include a longer very good quote:\nThe hardest part of memory management in C is working out when allocated memory should be freed again. As such, people come up with patterns to give rules for when they should free memory. Rust basically takes some of the most popular patterns, and bakes them into the language itself:\nSomething very common in library functions is \u0026ldquo;I got this pointer from somewhere else; I\u0026rsquo;m not going to worry about how it\u0026rsquo;s allocated and just use it\u0026rdquo;. This is Rust\u0026rsquo;s \u0026amp;T; you can do what you like with it apart from keeping copies of the pointer itself (because for all you know, it might be freed immediately after you return).\nAnother common pattern is \u0026ldquo;ownership semantics\u0026rdquo;, where the idea is that you designate a function/struct/whatever responsible for the lifetime of the pointer, and everything that no longer needs the pointer has to either pass it to something else (which takes ownership of it), or free it. This is Rust\u0026rsquo;s ~T, for the owner. (And if the owner passes temporary copies of it to other functions to look at, they get an \u0026amp;T.)\nFinally, for pointers with complex usage, many projects will simply use garbage collection or reference counting. This is Rust\u0026rsquo;s @T, which basically just tells the compiler to use a garbage collector on the pointer, and then you can pretty much do what you like with it (as in Java or another garbage-collected language). — ais523 http://www.reddit.com/r/programming/comments/10yb5q/rust_refining_traits_and_impls/c6hybv6 I do like these ideas and I think they would work wonders in communication between concurrent threads and more. But my head still easily has a hard time parsing the code. A final quote yet again warning about complexity:\n\u0026ldquo;The common liturgy of language design is that x feature makes development easier, less error prone, safer, etc. Nearly always, the precise way in which x feature does this is as clear as a bell. But somehow, as we multiply the number of features, something truly destructive starts to happen. It\u0026rsquo;s not just diminishing returns . . . I think about a language like C++. I can see the reasons for every single thing in it. I can understand the arguments for why this or that is a good thing. But it is perilously easy to write very unmaintainable code in this language, and to understand why, I think we have to get beyond the usual debates (static vs. dynamic, functional vs. OO, compiled vs. interpreted, etc). Small vs. large might be one place to start.\u0026rdquo;\nStill, I think Rust is going places as \u0026ldquo;a new C++\u0026rdquo;. Mozilla is pushing hard, the community is boiling, the developers seem sharp and although the language is quite immature - I don\u0026rsquo;t see any other modern strong competitor fighting for the same spot. C++ is not modern and no, I don\u0026rsquo;t think D will take off in any substantial way.\n587 forks and 267 contributors on github.\nDart Link to heading Ahhh. Dart annoys me. As a Smalltalker I should like it, but I have a hard time getting itchy to try it. Ok, so:\nSyntax: JavaScript and C# Object Model: Smalltalk Compilation Strategy: Self Optional Types: Strongtalk Isolates: Erlang (picked from a slideshow)\nIf one just takes a cursory look it looks like Java. It has the boring C curly brace syntax. It has types. But wait, it actually is NOT statically typed, it is dynamically typed. It turns out the types are simply \u0026ldquo;annotations\u0026rdquo; used by tools and giving more information to the developer. They are fully optional. They have ZERO function during runtime. And since the object model is basically from Smalltalk the net result is that Dart actually is very close to Smalltalk. And at the same time\u0026hellip; not.\nThings I find annoying already on paper:\nThe IDE is an Eclipse derivative, just as boring. It might be good compared to\u0026hellip; emacs. But as a Smalltalker it doesn\u0026rsquo;t excite me. Sure, I know the history of the Eclipse project, and I did really like VisualAge (even the Java variant was nice). The language, tools and libraries are very web centric. Sure, fine, but it doesn\u0026rsquo;t feel \u0026ldquo;general purpose\u0026rdquo; yet. Smart focus? Perhaps. The code looks so\u0026hellip; boring. I can\u0026rsquo;t help it but it really, really turns me off. The javascript integration looks pretty\u0026hellip; messy, on paper. Or did I miss something? Not sure. I think that part is heavily worked on though. And at the same time they are pushing hard, performance on their own VM looks very good (2x better than javascript more or less) and they seem to still be serious about it.\nSo I think Dart has potential, but at the same time\u0026hellip; it looks like Java, in order to attract Java people but\u0026hellip; what if Java people then still prefer Java? Will it attract enough web developers to get serious against javascript? Doubtful.\n15 committers on google code, almost all from google.\nJulia Link to heading Perhaps the most impressive of all these four languages is Julia. It\u0026rsquo;s a dynamically typed language that aims for C performance. Ok, so you have heard that one before, right? But Julia seems to not only be \u0026ldquo;huff and puff\u0026rdquo; - on a series of micro benchmarks Julia is already less than 2x slower than C on all of them. This means it beats V8 (js) on all of them and beats FORTRAN in 5 out of 7. Given that the Julia developers have \u0026ldquo;just started\u0026rdquo; I think they have a fair chance of reaching their goal, especially since they already match C on 2 of these micro benchmarks.\nSo a dynamically typed language with screaming performance? Ok, so Strongtalk was fast. And there are Smalltalk implementations that are quite fast, and Lisp of course. But matching C? Oooh, don\u0026rsquo;t know about you but I think that is a first.\nInteresting. And when you start looking closer you realize that Julia is more than a lanugage for math, for example this little blog post shows they are clearly pushing a few boundaries on the language front.\nJulia seems to be picking very good base C libraries for performance, same libuv that NodeJS uses, and of course many math libraries since after all - math is the focus of Julia.\nAnd oh, guess who I noticed posting on the Julia mailinglist? Avi Bryant (hey Avi!). Since Avi clearly has a nose for \u0026ldquo;good stuff\u0026rdquo; I find that very interesting! :) So I need to look closer at Julia, for sure. It has an academic feel so far, not at all a bad thing, but I hope they also manage to build a community and broaden the effort - not seldom has brilliant academic stuff failed to build a community and eventually withered away. On the other hand github indicates it is doing well so far!\n469 forks and 149 contributors on github.\nAnd Smalltalk? Link to heading Being a hard core Smalltalker I of course want to ask myself: How is the Smalltalk community stacking up against these new four challengers?\nThe top players in the open source (I only care about that) Smalltalk world today is Pharo and Amber IMHO. Pharo has its own JIT VM called Cog (shared with the Squeak project which Pharo forked from) which is not as fast as V8, but still quite fast. Pharo has a strong community and is evolving in an increasing speed.\nTraiditionally Smalltalk - given its design - has been less ideal when it comes to interfacing with external libraries. Sure, in Squeak/Pharo we have always had FFI, VM plugins etc, but no \u0026ldquo;automated wrapper thing\u0026rdquo; like Swig or such. And even if the FFI and plugin mechanism is there - the intricacies of interfacing with the C world and its notion of structs and pointers and basic C types have been fairly demanding. Smalltalk is a very pure OO language and just the issue of mapping and converting basic types can be hard.\nNow things are looking brighter because Igor Stasenko in the Pharo community has been pushing hard with the new low level infrastructure called NativeBoost (NB for short). NB is more or less a dynamic assembler implemented as a Smalltalk internal DSL. So yeah, you can write assembler - but in Smalltalk. And more importantly - you can do it dynamically during runtime. So in a more philosophical way Smalltalk is breaking out of its VM.\nWithout going any deeper, this is opening up new ways of interacting with the outside world of C libraries and the metal in general.\nThe Smalltalk community is one of those communities that will never die, just like Lisp I imagine. I am right now sitting at ESUG (Camp Smalltalk) together with 24 other Smalltalkers just hacking. If you look at SmalltalkHub.com - our very own github clone (written in Smalltalk of course, even the HTML5 client!) you will see that we are a long way from dead - 755 users and almost 1000 projects. Now\u0026hellip; SmalltalkHub is new and many projects are still moving into it from other older Smalltalk repositories, so these users/projects have signed up within the last year or so.\nOk, so if Pharo is our \u0026ldquo;answer\u0026rdquo; to server side, what about the web? The Smalltalk world has had Seaside , one of the best web frameworks ever. Period. But the world is moving fast and server side generation of HTML is not the future, HTML5 is. Or in other words, a javascript app manipulating the DOM. Dart is offering a \u0026ldquo;better path than javascript\u0026rdquo; but in Smalltalk we have something else, even better one might argue - Amber .\nThere is much to say about Amber, but basically it is a true Smalltalk implemented in and \u0026ldquo;on top\u0026rdquo; of Javascript. It has an advanced compiler pipeline, an IDE that runs directly in the browser (!) a working debugger (!!) and yeah, of course it runs wherever javascript runs - nodejs is fine. What sets Amber apart from Dart is probably that it is \u0026ldquo;live\u0026rdquo;, IDE runs in the browser and you can interactively develop your HTML5 app, and it interfaces beautifully with javascript, which I think is an issue with Dart (it might have improved).\nIn fact, SmalltalkHub.com is an Amber application. :)\nI think we are in a good shape, but perhaps we should:\nTake a closer look at Julia since it is so close to Smalltalk and has several interesting aspects (performance and very good math) Keep an eye on Rust, Dart and Go, if only for inspiration. Some of the ideas there are pretty slick. Perhaps even consider Rust as an interesting new language for VM construction. Phew.\nHappy hacking!\n"},{"title":"RethinkDB - Yet Another NoSQL?","permalink":"https://goran.krampe.se/2013/07/16/rethinkdb-yet-another-nosql/","summary":"\u003cp\u003e15-18 years ago my passion was in OODBs. As a Smalltalker \u003ca href=\"http://www.gemtalksystems.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eGemStone\u003c/a\u003e\n was one of the most fascinating to work with, but as we all know OODBs never got really popular, despite their fantastic qualities. But the new NoSQL databases in many respects offer OODB-ish characteristics, although they of course also bring a whole new menu to the table.\u003c/p\u003e\n\u003cp\u003eIn my eternal quest for \u0026ldquo;database bliss\u0026rdquo; my next stop is \u003ca href=\"http://rethinkdb.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eRethinkDB\u003c/a\u003e\n, but let me tell you how I got here.\u003c/p\u003e","content":"15-18 years ago my passion was in OODBs. As a Smalltalker GemStone was one of the most fascinating to work with, but as we all know OODBs never got really popular, despite their fantastic qualities. But the new NoSQL databases in many respects offer OODB-ish characteristics, although they of course also bring a whole new menu to the table.\nIn my eternal quest for \u0026ldquo;database bliss\u0026rdquo; my next stop is RethinkDB , but let me tell you how I got here.\nWhen it comes to NoSQL databases I have both worked and dabbled with a few:\nTokyo Tyrant . Yeah, it was extremely fast (still is) and I did implement a Squeak binding for its binary protocol, but nah, the use cases are very limited. But it was fun!\nCouchDB . A lot of nice design decisions with a very friendly HTTP oriented API, all JSON and interesting map/reduce mechanisms. CouchDB was one of the primary NoSQL databases to start the whole \u0026ldquo;movement\u0026rdquo; but although it\u0026rsquo;s brilliant in many ways it also wasn\u0026rsquo;t built to scale and it quickly got side tracked by the competition. Most other NoSQL databases have picked up quite a few tricks from Couch though so it has been very influential.\nRiak . Riak feels like \u0026ldquo;CouchDB done right\u0026rdquo;, same HTTP friendliness but a very robust Dynamo-inspired fully distributed architecture. If one wants a system that doesn\u0026rsquo;t trade availability for consistency - Riak is it. But there is a cost - you need to put a lot of effort into conflict resolution mechanisms (resolving siblings) - and that is not trivial to do. While Riak is very \u0026ldquo;seductive\u0026rdquo; in all its 100% Buzzword Compliance-ness, you might come to the conclusion that your use case actually isn\u0026rsquo;t the next Amazon or Facebook needing to serve millions of people at the same time with 99.99999 availability.\nHyperDex . This is a really fast database with several interesting mechanisms like hyper hashing. The only API is going through the C library, which can be a bit of a hard time from Pharo /Squeak. I started out with NativeBoost FFI (cool stuff Igor) for this but got stuck. Still very interesting and did I mention super fast? A bit immature (docs lacking) and it also depends on fixed schemas, not sure how to deal with schema migration. So, fascinating and FAST, with lots of cool functionality but\u0026hellip; doesn\u0026rsquo;t feel practical - there must be alternatives not needing fixed schemas? Why isn\u0026rsquo;t the \u0026ldquo;spaces\u0026rdquo; definition grammar documented? Who knows, HyperDex may be the Next Big Thing, but as of now I think I am moving on.\nSo where to go from here? Riak is great, but I want more consistency guarantees to eliminate all that conflict resolution work. This blog post nails it pretty good - it probably turns out I want something that is CP instead of AP like Riak is.\nAnd in case you wonder - MongoDB is not for me, I know\u0026hellip; some people love it, but let me quote (and there are many other sources too) the internetz:\nI would suggest you don\u0026rsquo;t try to use MongoDB in a high-availability mode (or at all if you can help it). It\u0026rsquo;s quite buggy, lacks useful features and isn\u0026rsquo;t in fact Consistent (even though its design might suggest it is). It\u0026rsquo;s just a bad database with too much marketing :( There are a few decent-looking Consistent databases out there (HBase, Couchbase, RethinkDB, Hyperdex) and several decent Eventually Consistent databases (Cassandra, Riak, Dynamo). — Lucian http://www.tbray.org/ongoing/When/201x/2013/05/06/Tab-Sweep-Tech#c1367917902.203869 So Google to the rescue, there must be more consistent NoSQL dbs out there\u0026hellip;\nFoundationDB . Sounds and looks very impressive \u0026ldquo;on paper\u0026rdquo; but it is not yet available and AFAICT it is not going to be open source either, so\u0026hellip; nope.\nCouchbase . Looks fairly interesting, Membase married to CouchDB, but their description of the \u0026ldquo;community edition\u0026rdquo; doesn\u0026rsquo;t feel that inspiring to me. They don\u0026rsquo;t really seem committed to open source, this is more a straight up commercial offering with \u0026ldquo;Enterprise trash talk\u0026rdquo;. So no, not me, and the muddled merge with CouchDB has at least left me utterly confused over this product and what it actually \u0026ldquo;is\u0026rdquo;.\nRethinkDB . Aha. I think this is my next NoSQL database to look closer at, I really like what I see, both technically and how they feel as a company - very open and they seem to really understand how open source works, culturally. And installing it and playing with the web console was trivial\u0026hellip; fun stuff!\nNow I just need to implement protobuf in Pharo\u0026hellip; :)\n"},{"title":"Going virtual from CLI","permalink":"https://goran.krampe.se/2013/01/21/going-virtual-from-cli/","summary":"\u003cp\u003eRecently when I automated a development process I looked deeper at managing virtual environments and ended up using two really nice tools complementing \u003ca href=\"http://www.virtualbox.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eVirtualBox\u003c/a\u003e\n in a slick way - \u003ca href=\"http://www.vagrantup.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eVagrant\u003c/a\u003e\n and \u003ca href=\"https://github.com/jedi4ever/veewee\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eVeewee\u003c/a\u003e\n. A lot of us use VirtualBox of course, but getting a new Ubuntu box up is still a bit of blablablabla\u0026hellip; What if it could be done \u003cem\u003eall from the command line and easily automated\u003c/em\u003e?\u003c/p\u003e","content":"Recently when I automated a development process I looked deeper at managing virtual environments and ended up using two really nice tools complementing VirtualBox in a slick way - Vagrant and Veewee . A lot of us use VirtualBox of course, but getting a new Ubuntu box up is still a bit of blablablabla\u0026hellip; What if it could be done all from the command line and easily automated?\nInstead of talking, let me show you how you can get a Ubuntu 12.10 box (as an example) up and running. Note that this should work on Ubuntu 12.10 (Quantal) and probably 12.04 too:\n# Base needed to get going, hope I didn\u0026#39;t miss anything important sudo apt-get install squashfs-tools genisoimage libxml2-dev zlib1g-dev libxslt1-dev ruby1.9.3 # New VirtualBox 4.2.0 (the one in Ubuntu proper is 4.1.x), it seems linux-headers are needed. wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add - sudo sh -c \u0026#39;echo \u0026#34;deb http://download.virtualbox.org/virtualbox/debian quantal contrib\u0026#34; \u0026gt;\u0026gt; /etc/apt/sources.list\u0026#39; sudo apt-get update \u0026amp;\u0026amp; sudo apt-get install linux-headers-generic virtualbox-4.2 # Vagrant and Veewee from gems, used to build Ororo basebox and appliance sudo gem1.9.3 install vagrant sudo gem1.9.3 install veewee As you can see I am installing VirtualBox 4.2.0, but 4.1.x probably works fine too. Ok, now that we have VirtualBox, Vagrant and Veewee we can get cracking. Veewee is a tool that adds some sub commands to Vagrant and automates the creation the VirtualBox instance from a vanilla OS ISO file that Vagrant then can control. Vagrant can then be used to bring such a box up, down and ssh into it and install lots of more software on it etc.\nLet\u0026rsquo;s pretend we are running a 64 bit Ubuntu on our machine but suddenly we want to compile some 32 bit libraries and the simplest way to do it is to just get a 32 bit virtual Ubuntu:\nmkdir quantal32 cd quantal32 vagrant basebox define quantal32 ubuntu-12.10-server-i386 vagrant basebox build quantal32 vagrant basebox validate quantal32 vagrant basebox export quantal32 vagrant box add quantal32 quantal32.box The steps:\nPick a template. Veewee offers lots of templates we can use and you can list them using veewee vbox templates (just run veewee for more commands). We picked ubuntu-12.10-server-i386. Build the box. You will see how VirtualBox pops up to life but everything is automated so don\u0026rsquo;t touch! Validate the box. This makes Veewee run a bunch of quick tests to check that the few things Veewee installed are all OK. The stuff installed can easily be inspected if you take a look in the sub dir definitions etc, it all has to do with making Vagrant happy for further provisioning etc. Export the box as a single file called quantal32.box that we could share if we wanted to. Add this exported box as a known basebox in Vagrant. This last step makes this basebox available to clone using Vagrant. Okidoki, so now we have progressed from a downloaded ISO file of vanilla unmodified Ubuntu to a preconfigured VirtualBox. Of course, if you think the above is too much work :) then you can find prebuilt baseboxes here . Let\u0026rsquo;s now create one of these puppies to use:\nmkdir mynewbox cd mynewbox vagrant init quantal32 vagrant up vagrant ssh The steps:\nWhen we init vagrant in our empty directory Vagrant will create a file called Vagrantfile in there. This file is actually a ruby script and you can edit it to customize your box. Since we gave a basebox name as the argument this file will include an entry config.vm.box = \u0026quot;quantal32\u0026quot;. The file could even include a URL to this basebox so if you had published the basebox somewhere you could actually send this Vagrantfile to some other developer (or commit to SCM). The up command simply brings the box up and running! Tada! And then we can ssh into it easily. For more details see the homepage of Vagrant. And when we are fed up with the box - just take it down with vagrant suspend (or halt) or nuke it with vagrant destroy. Just run vagrant for a list of commands.\nSo now whenever you need a clean 32 bit Ubuntu for some testing or such - create a directory, run init and up, and there you are. :)\nOf course, integrating these commands into Makefiles are quite simple too.\n"},{"title":"HyperDex on Ubuntu 12.10 from source","permalink":"https://goran.krampe.se/2013/01/16/hyperdex-on-ubuntu-12.10-from-source/","summary":"\u003cp\u003eSo ok, I really like looking at new interesting NoSQL databases. Up until yesterday I felt \u003ca href=\"http://basho.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eRiak\u003c/a\u003e\n was the most interesting one (have also coauthored \u003ca href=\"http://www.smalltalkhub.com/#!/~gokr/Phriak\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ePhriak\u003c/a\u003e\n - a Riak binding for \u003ca href=\"http://www.pharo-project.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ePharo Smalltalk\u003c/a\u003e\n) but after an evening of discussing choices of key/value backends for the \u003ca href=\"/categories/oak\" \u003eOak\u003c/a\u003e\n project I decided to \u0026ldquo;google a bit\u0026rdquo; and stumbled upon \u003ca href=\"http://hyperdex.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eHyperDex\u003c/a\u003e\n.\u003c/p\u003e","content":"So ok, I really like looking at new interesting NoSQL databases. Up until yesterday I felt Riak was the most interesting one (have also coauthored Phriak - a Riak binding for Pharo Smalltalk ) but after an evening of discussing choices of key/value backends for the Oak project I decided to \u0026ldquo;google a bit\u0026rdquo; and stumbled upon HyperDex .\nWithout having had the pleasure to actually play with it yet - on paper - it sure looks like a killer NoSQL database. It seems to offer basically the same kind of robustness and horisontal \u0026ldquo;just add another box\u0026rdquo; kind of scalability that Riak offers including auto balancing etc. But at the same time it offers awesome raw speed beating both MongoDB (without cheating like Mongo does) and even Redis, although HyperDex is truly persistent. And to put sugar on top - it has atomic operations in Redis style and manages to somehow avoid the eventual consistency corner - not sure about the details around that.\nIn summary - an extremely interesting NoSQL database.\nBuilding from source Link to heading NOTE: You don\u0026rsquo;t need to build anymore, as of release 1.0.rc5 there are binaries available for Ubuntu\nThe instructions on how to build HyperDex from source were a tad incomplete. So I offer the following procedure that seemed to work for me in a relatively clean Ubuntu 12.10.\nFirst we need a bunch of tools (updated 2013-01-17 with some corrections from Robert Escriva):\nsudo apt-get install git autoconf automake autoconf-archive libtool python-dev python-pyparsing cython libpopt-dev libcityhash-dev g++ libgoogle-glog-dev libleveldb-dev bison gperf flex python-sphinx Then we need a bunch of git clones:\ngit clone git://git.hyperdex.org/po6.git git clone git://git.hyperdex.org/e.git git clone git://git.hyperdex.org/busybee.git git clone git://git.hyperdex.org/replicant.git git clone git://git.hyperdex.org/HyperDex.git Then, in the order listed above, do the following in the first four:\nautoreconf -i; ./configure; make \u0026amp;\u0026amp; sudo make install \u0026hellip;and perhaps something like this in HyperDex:\nautoreconf -i; ./configure --enable-python-bindings; make \u0026amp;\u0026amp; sudo make install If all is well you should be able to find the hyperdex command in your path and if hyperdex daemon --help provides helpful output then all is probably fine. For more details take a look in HyperDex/doc/02.installation.rst.\nHappy hacking!\n"},{"title":"New SSD for my Lenovo X220","permalink":"https://goran.krampe.se/2013/01/10/new-ssd-for-my-lenovo-x220/","summary":"\u003cp\u003eAfter the \u003ca href=\"/2013/01/02/ssd-nightmare\" \u003econundrum with my Intel 320 SSD\u003c/a\u003e\n I did some googling and decided to invest a fair chunk of money in a really good SSD - the \u003ca href=\"http://www.anandtech.com/show/6328/samsung-ssd-840-pro-512gb-review\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSamsung 840 Pro, 512GB\u003c/a\u003e\n. The 840 Pro seems to be the king of the hill right now and it\u0026rsquo;s only 7mm thick which is what I need for my X220 (although people have shoved 9mm drives into it with a bit of force).\u003c/p\u003e","content":"After the conundrum with my Intel 320 SSD I did some googling and decided to invest a fair chunk of money in a really good SSD - the Samsung 840 Pro, 512GB . The 840 Pro seems to be the king of the hill right now and it\u0026rsquo;s only 7mm thick which is what I need for my X220 (although people have shoved 9mm drives into it with a bit of force).\nThe actual replacement was trivial, one normal screw to remove the lid on the side, pull out the old disk, move the plastic rails over to the new disk (just pull off and slide onto the new drive), add a piece of tape as a pull handle (to make it easy to remove) and slide it in. If it doesn\u0026rsquo;t want to go in you need to flip the rails.\nReboot, go into BIOS and make sure AHCI is selected for SATA and off to happy land. I installed Ubuntu 12.10 from a USB stick and just let it do the automatic thing. This creates a swap partition on the SSD, but that is fine with me - I adjust the swappiness instead to make sure it is only used when really needed.\nYou can test performance to make sure all looks ok:\nhdparm -tT /dev/sda \u0026hellip;or whatever /dev you have. I get around 7000MB/sec for cached reads and 515 MB/sec for buffered reads.\nIn /etc/fstab I added the options \u0026ldquo;noatime,nodiratime,discard\u0026rdquo;. The \u0026ldquo;nodiratime\u0026rdquo; is not really necessary since it is implied by noatime. This makes Linux not update access time on files which in turn reduces write operations a lot which prolongs the life of the SSD and increases performance.\nThe \u0026ldquo;discard\u0026rdquo; option is to make sure we enable TRIM on the disk. I just followed this article (and this other ) describing it and how to test it works. Another good page on AskUbuntu . Some people say that the test in that article is not reliable, but still, if you do get zeroes then you can rest assured it works. :)\nNext up is setting down swappiness, changing to a disk scheduler more suitable for an SSD and setting /tmp up using tmpfs in RAM. I will not repeat all this - instead I offer some links to good instructions at Tombuntu or in the ArchLinux wiki or this one going even deeper .\nRergarding partition alignment - I read that it should be automatic so I didn\u0026rsquo;t bother looking into that.\n"},{"title":"Moving to SmalltalkHub","permalink":"https://goran.krampe.se/2013/01/07/moving-to-smalltalkhub/","summary":"\u003cp\u003eAs a long time Squeak/Pharo (Smalltalk) developer I have accumulated a set of packages that I have written or co-written and that have been published open source for others to use. Since quite a few years \u003ca href=\"http://www.squeaksource.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSqueakSource\u003c/a\u003e\n has been the natural hosting place, but it has reached the end of the road and it\u0026rsquo;s \u003ca href=\"http://news.squeak.org/2012/11/18/move-your-squeaksource-files/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ehigh time to move on\u003c/a\u003e\n.\u003c/p\u003e","content":"As a long time Squeak/Pharo (Smalltalk) developer I have accumulated a set of packages that I have written or co-written and that have been published open source for others to use. Since quite a few years SqueakSource has been the natural hosting place, but it has reached the end of the road and it\u0026rsquo;s high time to move on .\nSince then we have had SqueakSource2 (an improved SqueakSource but not deployed I think) and now SqueakSource3 that runs in GemStone and hosted by GemStone. A lot of projects have migrated to SS3 and that is definitely not a bad choice and has been the suggested and only path forward for some time. Never mind it says \u0026ldquo;public Alpha\u0026rdquo; :)\nPersonally though I find SmalltalkHub more attractive - but this is perhaps because I am involved in some of the technology behind it and I know Nicolas quite well. Anyway, I am now moving (well, copying) all my projects there and the process to moving is simple and has been described for SS3 over a year ago:\nCreate a project on SH. And if you don\u0026rsquo;t have an account, create one.\nRun a few snippets using Gofer to copy over all the code. Here is an example copying over all snapshots for DeltaStreams, PlusTools and System in the DeltaStreams project on SS to my new project on SH:\nGofer it url: \u0026#39;http://www.squeaksource.com/DeltaStreams\u0026#39; username: \u0026#39;gokr\u0026#39; password: \u0026#39;secretpasswordonSS\u0026#39;; package: \u0026#39;DeltaStreams\u0026#39;; package: \u0026#39;PlusTools\u0026#39;; package: \u0026#39;System\u0026#39;; fetch Gofer it url: \u0026#39;http://smalltalkhub.com/mc/gokr/DeltaStreams/main\u0026#39; username: \u0026#39;gokr\u0026#39; password: \u0026#39;secretpasswordonSH\u0026#39;; package: \u0026#39;DeltaStreams\u0026#39;; package: \u0026#39;PlusTools\u0026#39;; package: \u0026#39;System\u0026#39;; push In the above code we need to list all packages that exists in this repository in order for Gofer to pick them all up. So you might want to look in the SS web UI (tab \u0026ldquo;Versions\u0026rdquo;) to make sure you didn\u0026rsquo;t miss any snapshots.\nEdit the package description on SS to reflect that SS is no longer the primary repository for this package: \u0026lt;b\u0026gt;NOTE: This project has been moved to \u0026lt;a href=\u0026#34;http://smalltalkhub.com/#!/~gokr/DeltaStreams\u0026#34;\u0026gt;http://smalltalkhub.com/#!/~gokr/DeltaStreams\u0026lt;/a\u0026gt;\u0026lt;/b\u0026gt;!!! To make it extra clear I also include a line like below on SH to make sure people understand this is the right place now: NOTE: As of 2013-01-06 this is the primary repository of DeltaStreams, there is also an old repository on www.squeaksource.com .\nFinally, if you have other people than yourself with write access on SS, make sure you check and add them as contributors in SH, if they have accounts on SH. And make sure to drop them an email! :) And poh, a little bird just told me that SH is being upgraded by the end of the week with new functionality and bug fixes. Go Nicolas, go!\n"},{"title":"Never an Intel SSD again","permalink":"https://goran.krampe.se/2013/01/02/never-an-intel-ssd-again/","summary":"\u003cp\u003eWhen I bought my Lenovo X220  - which I have been \u003cstrong\u003eextremely pleased with\u003c/strong\u003e to date - I chose an \u003cstrong\u003eIntel 320 160Gb SSD\u003c/strong\u003e disk with it, in retrospect a \u003cstrong\u003eBAD MISTAKE\u003c/strong\u003e. No idea why I didn\u0026rsquo;t find the warnings plastered all over the net at the time, and the problem was even acknowledged by Intel \u003ca href=\"http://www.techpowerup.com/149064/Intel-Acknowledges-SSD-320-Series-8-MB-Bug-.html\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eas early as july 2011\u003c/a\u003e\n. The disk has been working fine since april when I got it, until the last day of 2012\u0026hellip;\u003c/p\u003e","content":"When I bought my Lenovo X220 - which I have been extremely pleased with to date - I chose an Intel 320 160Gb SSD disk with it, in retrospect a BAD MISTAKE. No idea why I didn\u0026rsquo;t find the warnings plastered all over the net at the time, and the problem was even acknowledged by Intel as early as july 2011 . The disk has been working fine since april when I got it, until the last day of 2012\u0026hellip;\nThe laptop has experienced \u0026ldquo;freezes\u0026rdquo; from time to time - you know, when the only thing you can do is hold the ON button to shut it off hard. I have been suspecting bad memory, but every time I tested they seemed fine. Yesterday I ran memtest for 5 hours on them and no, no problem there. I would guess this has happened perhaps 15 times since I got the machine in april - so about 15 power cycles is all it took to make 2012 end with a BANG.\nAfter this last freeze and power cycle the machine suddenly ended up at the grub prompt and couldn\u0026rsquo;t boot. Not a reassuring feeling. Playing around at the grub prompt the partitions seemed to look fairly fine though, I could see \u0026ldquo;most\u0026rdquo; of my files.\nAfter getting myself a bootable USB rescue disk I managed to access the disk and copy my home catalog to an external disk - phew! My backup was at least a week old so thank you, thank you disk Gods for allowing me to do this. \u0026hellip;then I did another reboot to try to figure things out and suddenly not even a grub prompt!\nEhrm, what? WHAT? I started scavenging the net and behold - this seems to be the well known so called \u0026ldquo;BAD_CONTEXT or BAD_CTX 8MB bug\u0026rdquo; that the Intel 320 based SSD drives are plagued with. So power cycling can apparently trigger this - and the disk for some odd reason (self protection?) decides to decapitate itself and set accessible cylinders down to 16 instead of 16384.\nFunny thing here is that the last reboot was NOT a power cycle, but for some reason the SSD decided that \u0026ldquo;enough is enough\u0026rdquo; and chopped off its head in desperation.\nThis is of course a legacy thing, SSDs don\u0026rsquo;t have cylinders of course, but the net effect is that the disk appears to be only 8MB large. It seems (googling conclusion) this happens whenever the SSD experiences ANY disastrous error, so not only this particular \u0026ldquo;bug\u0026rdquo;.\nAnd in fact, I am not even sure my disk got the same bug, because after the BAD_CTX there is a number, and mine says \u0026ldquo;15\u0026rdquo;. The one people talk about, and that Intel claims to have fixed with a firmware update, is number \u0026ldquo;13\u0026rdquo;. But fact remains, my disk is not accessible and it was apparently trigged by a power cycle.\nSince the disk uses encryption internally (I think this is one of the reasons) there is apparently no way for ordinary people to salvage any data. And I can\u0026rsquo;t even persuade the disk to even show me the rest of the disk. When the upper bound is set down like this the \u0026ldquo;hidden\u0026rdquo; area (most of the disk in this case) is called a Host Protected Area . Using hdparm and other tools one is supposed to be able to set this \u0026ldquo;SET MAX ADDRESS\u0026rdquo; threshold back up and remove this \u0026ldquo;protected area\u0026rdquo;, but all my fiddling with this has utterly failed. I tried hdparm and HDAT2 using ultimatebootcd but no, no go. It just gives me some error when I try.\nAnd the rest of the net also says that the contents of the disk is lost but that you can reset the disk so that it at least \u0026ldquo;works\u0026rdquo; again , but empty. And another post describing a different procedure .\nNow\u0026hellip; there is some data salvage firm claiming they can save data from this problem (sorry, no link from me, but if you are in this situation you will find them) - and I think they have cooperated with Intel to be able to do this. I would guess Intel has provided some \u0026ldquo;super keys\u0026rdquo; to the encryption in that case? Who knows. I haven\u0026rsquo;t lost enough data to contact them though.\nSo\u0026hellip; it seems the net is in fact quite enraged over Intel for all this - because this drive (and SSDs in general) is supposed to be very safe and actually has special features for preventing these exact things! How ironic.\nNow, Intel is stone walling, they claim to have fixed the problem with the firmware update - but lots of people are reporting the same issue happening again, over and over, even with updated firmware\u0026hellip; And no answers from Intel.\nAnd you might ask, what about my firmware? Well, this is a Lenovo OEM (INTEL SSDSA2BW160G3L), so it has a Lenovo firmware number (4PC1LE04) but I did go through the Intel firmware update dance (unetbooting from Linux onto USB stick works fine) and it tells me that my firmware IS UP TO DATE. No, it doesn\u0026rsquo;t tell me that I have some Lenovo firmware that it doesn\u0026rsquo;t know about - it says IT IS UP TO DATE. So I trust Intel on that one. Ha, silly me. So yes, chalk me up as one of those that had new firmware and got hit by the truck anyway.\nIMHO hardware that has faults is generally not a big problem, it doesn\u0026rsquo;t generally cause lots of data loss if a graphics card or a motherboard burns up. But disks with bugs like this is more problematic. And we are not talking about \u0026ldquo;a few sectors lost\u0026rdquo; but the whole 100% shebang lost.\nBackups? Sure. But you will generally still lose lots of valuable time when a thing like this happens, and I don\u0026rsquo;t think it is enough to just point the finger back at the customer like that. Sure shit happens, but here we are talking about known about and repeatedly happening after less than a year due to freaking bugs shit and not just weared down by 10 years of continuous spinning shit.\nWhat makes it more than \u0026ldquo;a problem\u0026rdquo; is that Intel doesn\u0026rsquo;t respect its customers enough to:\nexplain what is going on explain what these different error numbers mean explain why it truncates to 8MB explain why people still have problems after the firmware update explain what the firmware update claims to have fixed \u0026hellip;and take responsibility when their product is obviously badly broken and not trustworthy - that is much more than \u0026ldquo;a problem\u0026rdquo;!\nBoycotting Intel is not an easy thing, but one thing is for sure, I will NEVER buy an SSD from Intel again. NEVER. And if you google the net you will see lots of other people with the same conclusion.\nIf Intel doesn\u0026rsquo;t care about their customers and their own goodwill - so be it. And if someone from Intel wants to comment on this blog post - feel free - but I truly doubt it since they don\u0026rsquo;t even comment in their own damn forum which is full of posts like this one .\nAnd if there are factual errors in this text and Intel somehow miraculously can explain all this crap - go ahead and contact me and I will HAPPILY edit the text and explain to the world what I completely misunderstood.\nSo\u0026hellip; end of steam. Anyone that can recommend a good trustworthy SSD that fits in a Lenovo X220?\nNo idea what I will do with this old one, I sure don\u0026rsquo;t trust it anymore and getting another one on warranty wouldn\u0026rsquo;t make it different.\nUPDATE: As I write in my comment below I revived the SSD but it\u0026rsquo;s now just wasting space on my desk here. I instead bought a Samsung 840 Pro, 512Gb (here is one of all reviews ), yes, expensive but seems to be extremely fast (only 1-2 other SSDs are even close), uses very little power (no other SSD seems to be close) and above all - Samsung seems to have a better track record on robustness and how to deal with problems. Of course, I will know more in a year from now, and I am also investing some time into a full recovery solution like Mondo Rescue or similar. :)\n"},{"title":"Oak","permalink":"https://goran.krampe.se/2012/12/29/oak/","summary":"\u003cp\u003eIn a customer project right now I need to be able to work and evolve code fast, with a relatively complex model. And by \u003cem\u003efast\u003c/em\u003e I mean that I want to cut away as much as possible of the efforts related to persistence. Generally this is what OODBs excel at.\u003c/p\u003e\n\u003cp\u003eIn the Squeak world we have \u003ca href=\"http://www.gemstone.com/products/gemstone\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eGemStone\u003c/a\u003e\n (commercial), \u003ca href=\"http://wiki.squeak.org/squeak/3492\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eGOODS\u003c/a\u003e\n and \u003ca href=\"http://wiki.squeak.org/squeak/2665\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eMagma\u003c/a\u003e\n as \u0026ldquo;full fledged\u0026rdquo; OODBs. Last century :) I worked with GemStone (both Gemstone/S and /J) and its a great product - but I want something lightweight and open source. And simple. And hackable. And new. :)\u003c/p\u003e\n\u003cp\u003eI also used Magma in the Gjallar project, and while I respect it highly - this time I want to try something with an \u0026ldquo;externally supported backend\u0026rdquo;. I also had a mixed performance experience, but this was \u0026ldquo;pre Cog\u0026rdquo; and Magma has also surely evolved lots since then, and I am not sure we did everything the way we should have either.\u003c/p\u003e\n\u003cp\u003eSandstoneDB could also be interesting to look more closely at, but since I have been working with \u003ca href=\"http://www.nicolas-petton.fr\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNicolas Petton\u003c/a\u003e\n on improving \u003ca href=\"http://smalltalkhub.com/#!/~gokr/Phriak\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ePhriak\u003c/a\u003e\n (Riak interface for Pharo) it was natural to take a look at one of his \u0026ldquo;under the radar\u0026rdquo; projects - \u003ca href=\"http://www.smalltalkhub.com/#!/~NicolasPetton/Oak\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eOak\u003c/a\u003e\n, an \u0026ldquo;OODBish\u0026rdquo; solution on top of Riak. At this point I have been doing much more than looking, in fact I am hacking on it! And oh, yeah, of course there are \u003ca href=\"http://wiki.squeak.org/squeak/512\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003elots more persistence options\u003c/a\u003e\n available too.\u003c/p\u003e","content":"In a customer project right now I need to be able to work and evolve code fast, with a relatively complex model. And by fast I mean that I want to cut away as much as possible of the efforts related to persistence. Generally this is what OODBs excel at.\nIn the Squeak world we have GemStone (commercial), GOODS and Magma as \u0026ldquo;full fledged\u0026rdquo; OODBs. Last century :) I worked with GemStone (both Gemstone/S and /J) and its a great product - but I want something lightweight and open source. And simple. And hackable. And new. :)\nI also used Magma in the Gjallar project, and while I respect it highly - this time I want to try something with an \u0026ldquo;externally supported backend\u0026rdquo;. I also had a mixed performance experience, but this was \u0026ldquo;pre Cog\u0026rdquo; and Magma has also surely evolved lots since then, and I am not sure we did everything the way we should have either.\nSandstoneDB could also be interesting to look more closely at, but since I have been working with Nicolas Petton on improving Phriak (Riak interface for Pharo) it was natural to take a look at one of his \u0026ldquo;under the radar\u0026rdquo; projects - Oak , an \u0026ldquo;OODBish\u0026rdquo; solution on top of Riak. At this point I have been doing much more than looking, in fact I am hacking on it! And oh, yeah, of course there are lots more persistence options available too.\nWhat is Riak? Link to heading To understand Oak one should probably learn a bit about Riak first. Riak is the primary backend for Oak, although one can use different backends quite easily. The core Oak functionality only needs a key/value store. As Oak evolves I however suspect that some features will be more tightly associated with specific functionality in Riak, like the use of indexing and map/reduce. Nicolas has experimented with using MongoDB and combining with memcached , and I am intrigued to also test if Oak can run nicely on top of my Tokyo Tyrant binding. Bottom line is that while Oak is indeed abstracted on top of a key/value store - we are still focusing on Riak as the primary platform.\nRiak is an open source ultra scalable key/value store modelled after the highly influential Dynamo database built and used internally at Amazon. The architecture of Riak sets it apart from most of its competitors - it is completely masterless. All nodes participate in a \u0026ldquo;hash ring\u0026rdquo; and key/value pairs are stored redundantly on multiple nodes in parallell. Automatically. If one box burns up, nothing happens because data is spread out and Riak will compensate the loss of a node by automatically rebalancing data.\nIf you want more requests/second (reads or writes) just add more boxes. On the fly. Anyway, this article is not about Riak, but having Riak at the bottom we have the ability to scale and best of all, we can sleep calm at night. There is a lot of advanced algorithms involved in Riak to make all this work, but from the outside it is a beautifully simple system.\nThe binding we use for Riak is called Phriak and it\u0026rsquo;s an HTTP binding (Riak also offers a Protocol Buffer API) written using Zinc. Phriak can be used all by itself and covers quite a lot of Riak features including secondary indexes and map reduce. Finally, Riak is \u0026ldquo;data agnostic\u0026rdquo; so we don\u0026rsquo;t need to store JSON if we do not want to.\nInstalling Oak Link to heading I am using Pharo 1.4 and there is a Metacello configuration available on SmalltalkHub so load it:\nGofer it url: \u0026#39;http://www.smalltalkhub.com/mc/NicolasPetton/Oak/main\u0026#39;; package: \u0026#39;ConfigurationOfOak\u0026#39;; load. (Smalltalk at: #ConfigurationOfOak) project stableVersion load. Then you need Riak and there are detailed instructions available and it is generally quite simple. Currently Oak does not use secondary indexing so at this point Riak should work fine, later when we start messing with secondary indexing you will need to switch to LevelDB as the backend library, but that is just a simple config tweak.\nNow, open up TestRunner, filter on \u0026ldquo;Oak\u0026rdquo;, select \u0026ldquo;Oak-Tests\u0026rdquo;, then click \u0026ldquo;Run Selected\u0026rdquo; - if all is fine you should have 40 green tests. OAOakSessionTest is running against your local Riak. OASessionMockTest is just running against a Dictionary in the image.\nHow does Oak work? Link to heading Oak is a layer on top of a key/value store creating a semi transparent OODB. By \u0026ldquo;semi transparent\u0026rdquo; I mean that it is slightly less \u0026ldquo;automagic\u0026rdquo; than a real OODB, but on the other hand there is much less code and logic that can go wrong and we get the luxury of leaning against a rock solid industry strenght backend. We are also gradually making it more and more transparent.\nOak has some fundamental mechanisms:\nSerialization of objects using Fuel, no mapping to JSON. The concept of a transaction/\u0026ldquo;unit of work\u0026rdquo; which can be committed as a whole or aborted, no explicit write operations. The concept of \u0026ldquo;persistence by reachability\u0026rdquo;, no explicit insert operations (but we still need explicit delete). Proxies to do automatic \u0026ldquo;faulting\u0026rdquo; of more objects from disk, no explicit read operations. So Oak doesn\u0026rsquo;t convert to JSON, instead we store Fuel blobs. Fuel is fast, heavily tested and supports schema changes. When it comes to generic serialization I would guess it is the best we have. We simply give Fuel an object to serialize into a ByteArray and Fuel follows all references and makes a blob for us.\nThe Oak transaction keeps track of all changes during a \u0026ldquo;unit of work\u0026rdquo; and applies them at the end, or not at all. The transactions are not truly atomic, but at least we postpone all operations until at the end, so if one decides to abort half way through - nothing is written. If the actual writing of the changes would fail it would still be non atomic. The operations we collect are basically delete, insert and update of Oak objects. An Oak object is a partial object graph.\nPartial? Well, let\u0026rsquo;s say we have a domain object Person. It might be arbitrarily complex but since it is a domain object it is designed to be self contained and not referencing UI stuff etc. We can save this single object in Oak like this:\n\u0026#34;Get a session object for localhost, port 8098 where Riak is running by default\u0026#34; session := OAOakSession newDefault. \u0026#34;Create our domain object, no need to do this inside a transaction in fact\u0026#34; person := Person new name: \u0026#39;Goran\u0026#39;; yourself. \u0026#34;All modifications we do must be inside a transaction. #setRoot: is used to save the single top level object in Oak.\u0026#34; session commit: [ session setRoot: person ] First of all, Oak doesn\u0026rsquo;t require anything special from the objects it saves. No need to inherit a base class or do any other kind of pre-processing.\nOne wouldn\u0026rsquo;t normally save a Person as the root. A more normal approach would be to save a Dictionary there, and then save other objects in it. Or set your domain top level object of your system as the root.\nWhen objects are saved, Oak will use a \u0026ldquo;UUID new asString36\u0026rdquo; as the key. We call this key the \u0026ldquo;oid\u0026rdquo; (Object id) of the object. So in order to get an object back we would either need to know the oid or we get the object through some other object by reachability, typically starting at the root object. The root object is saved using a hard coded oid, so we can always find that one.\nNow, let\u0026rsquo;s modify the person. Reuse the session you have, or create a new one. Let\u0026rsquo;s focus on the interesting bit:\nsession commit: [ | person | person := session root. person name: \u0026#39;Nicolas\u0026#39;. person oakSave ] When we send #root to the session it will actually not read the Person, it will instead create a proxy object which has a single instance variable holding the oid, which in this case is the hard coded oid for the root object. So the temp variable \u0026ldquo;person\u0026rdquo; will hold the proxy. The magic happens when we send #name: to this proxy. It will trap the message, fetch the Person instance from Riak (as a Fuel ByteArray) and materialize it into a \u0026ldquo;real\u0026rdquo; Person instance. Then the proxy will forward the #name: message to this Person instance and return whatever it returns.\nMost OODBs tend to use #become: to actually turn the proxy into the real object. Oak currently does not do this, instead Oak keeps forwarding. There are advantages and disadvantages of both approaches. If one uses \u0026ldquo;short\u0026rdquo; transactions - quickly find your way down to your object, modify and commit - then you will send few messages and the commit will be quick. In this scenario one might argue that the cost of #become: is higher than doing a few message forwards. Perhaps Oak will use #become: later, the obvious advantage is that it enables more fool proof handling of identity.\nThen we send #oakSave to the proxy, and this will schedule an update operation which in turn will be executed after the commit block has run to the end. The #oakSave has two functions here. First it tells Oak that the object is dirty and needs to be written to disk. Secondly it tells Oak that this object should be a separate Oak object, serialized, read and written as a separate key/value pair in Riak with its own oid.\nIn fact, Oak also implements #oakInsert but there is no real need to use it, because one can always use #oakSave and it will itself decide to use insert if the object is a new object. Finally we have #oakDelete to actually delete an object. Oak has no garbage collection at this point so it is not enough to just \u0026ldquo;not reference\u0026rdquo; an object anymore. Well, nothing bad happens if you forget to send #oakDelete, but the key/value pair will still be in Riak consuming disk space.\nNow\u0026hellip; lately we have added autoSave so one do not need to use #oakSave at all! This mechanism does two things automatically:\nIt will detect which objects have been changed during the commit block and will save them automatically. This costs a little bit of performance, but nothing dramatic. It will also detect insertions automatically, but this depends on the instance answering true when asked #isOakPersistentWannabe. If an object answers true it means that it wants to be a separate Oak object if it happens to be reachable from another persistent Oak object. If it answers false it will not be saved as a separate key/value pair, instead it will be contained within the serialization of the object referencing it. So if we use autoSave we simply implement #isOakPersistentWannabe as \u0026ldquo;^true\u0026rdquo; in those domain objects that we think should be serialized as separate key/value pairs. Neat!\n##Next in Oak Next steps for Oak are probably:\nPolishing code by using it for real. :) Adding custom Oak collection classes that behaves like \u0026ldquo;normal\u0026rdquo; collections but leverage things like secondary indexing and map/reduce. Possibly adding some kind of automatic deletion. Custom collection classes one would like to have is of course large scale OrderedCollection and large scale Dictionary for starters.\nWhen it comes to deletion there are some things we can do. First we could automatically handle the special case of a single owner. If an object \u0026ldquo;promise\u0026rdquo; us that it is only referenced by ONE other Oak object, typically an owner, then we can automatically delete it when that owner \u0026ldquo;drops\u0026rdquo; it. For hierarchical models this would work, but of course it depends on the developer being sure these objects are only referenced from one and one object only. Since it wouldn\u0026rsquo;t solve the general case it might not be worth implementing it at all, not sure.\nThis turned into a rather long article, I hope that I have managed to tickle your interest and that you take Oak out for a spin and perhaps help out in making it better.\n"},{"title":"Moved from Wordpress to Octopress","permalink":"https://goran.krampe.se/2012/12/27/moved-from-wordpress-to-octopress/","summary":"\u003cp\u003eSo… I kinda got tired of Wordpress. A bit too much for me, I want something more lightweight that “just works”. I also stumbled over some blog that had just moved over to Octopress and made it sound like “da shit” for coders. So be it! And so far so good.\u003c/p\u003e\n\u003cp\u003eIn short I did an XML export from inside Wordpress admin, created an account on Disqus, added the disqus plugin for Wordpress, exported over all comments, then “git cloned” Octopress onto my laptop, used exitwp (from github) to migrate my XML file from Wordpress, used rsync deploy over to my server and adjusted config in Octopress to use disqus (and thus pick up all old comments).\u003c/p\u003e","content":"So… I kinda got tired of Wordpress. A bit too much for me, I want something more lightweight that “just works”. I also stumbled over some blog that had just moved over to Octopress and made it sound like “da shit” for coders. So be it! And so far so good.\nIn short I did an XML export from inside Wordpress admin, created an account on Disqus, added the disqus plugin for Wordpress, exported over all comments, then “git cloned” Octopress onto my laptop, used exitwp (from github) to migrate my XML file from Wordpress, used rsync deploy over to my server and adjusted config in Octopress to use disqus (and thus pick up all old comments).\nYeah, that’s about it. :)\n"},{"title":"Literal arrays vs JSON vs STON vs Tirade","permalink":"https://goran.krampe.se/2012/05/08/literal-arrays-vs-json-vs-ston-vs-tirade/","summary":"\u003cp\u003eRecently there were a range of threads on the pharo-dev mailinglist discussing the textual format to use for Smalltalk source code metadata. The discussion veered off from the specific use case but basically four different formats were discussed and compared, of which one I am the author. And oh, sorry for the formatting of this article - I need to change theme on this blog for better readability.\u003c/p\u003e","content":"Recently there were a range of threads on the pharo-dev mailinglist discussing the textual format to use for Smalltalk source code metadata. The discussion veered off from the specific use case but basically four different formats were discussed and compared, of which one I am the author. And oh, sorry for the formatting of this article - I need to change theme on this blog for better readability.\nJSON Link to heading The first format is JSON , Javascript Object Notation. JSON is a simple language neutral (despite its name) readable format that is very small to implement. It is a restricted variant of the native JavaScript literal syntax for objects (dictionaries) and arrays. Basically it excels in simplicity but lacks a bit in features, but people tend to ignore those shortcomings due to its widespread adoption. I will not go into describing it, json.org does a very good job and there are TONS of JSON implementations around.\nSTON Link to heading Sven Van Caekenberghe recently created a variation on JSON he calls STON , Smalltalk Object Notation. STON is basically JSON plus the following:\nObject references, the concept of being able to refer to other previously described arrays/objects in the STON file. This is done by number using the @-sign like \u0026ldquo;@2\u0026rdquo; refers to the second array/object in the file.\nClass prefixing, the idea of annotating arrays and objects (JSON terminology) so that one can instantiate a reasonable class when reading.\nSymbols, simply adding support for a primitive data type for Smalltalk symbols, although I do note - a limited form of Symbols not allowing the same range of characters in them as Squeak/Pharo does.\nThen there are a few subtle differences from JSON, like using $\u0026rsquo; instead of $\u0026quot; as string delimiter and nil instead of null, but not much else that I can see. Numbers seem to be exactly the same as in JSON, and escape codes inside strings are also the same, obviously by design.\nFirst I admit that I have not played with STON, my comparison is purely in theory. STON has the same basic positive notes that JSON has, it is small, simple and well defined. But are the differences worth it?\nJSON is everywhere and there are already tons of parsers for it, probably in every Smalltalk on earth, and of course all other languages too. STON on the other hand is Smalltalk only, and as of this writing probably Pharo only, although I admit it must be simple to port.\nIt boils down to if the additions are worth it and I don\u0026rsquo;t think they are. Embedding class names, if needed, could be done in JSON, although slightly inelegantly of course, but one approach would be to wrap each \u0026ldquo;typed\u0026rdquo; object/array in an object like this:\nByteArray [1, 2, 3] ==\u0026gt; {\u0026quot;type\u0026quot;: \u0026quot;ByteArray\u0026quot;, \u0026quot;data\u0026quot;: [1, 2, 3]} I agree, clunky, but on the other hand I tend to think that the parsing end needs to know the semantics and construction of the JSON anyway - JSON is too \u0026ldquo;simplistic\u0026rdquo; to be used as a true generic serialization mechanism and trying to turn it into such a beast by adding types and references, like STON does, is IMHO not that useful.\nSTON looks neat, but in practice** I don\u0026rsquo;t think the benefits outweigh the ubiquity and availability of JSON**. Had it been even more different it might have been another story. But if we don\u0026rsquo;t think we will use type annotations and circular references - then why not simply use JSON?\nLiteral Smalltalk arrays Link to heading The simplest notation of all in the lineup is the literal array syntax in Smalltalk. The example below covers all its capabilities AFAIK (in Pharo/Squeak), please tell me if I missed anything:\n#(4711 3.4 16r3F 'string' #symbol #'another-symbol' (nested array) #(one more) true false nil $x #[12 32]) So we have space separated elements and arrays that can nest, with or without #-prefix inside the array. Primitive literals are numbers (full numeric Smalltalk parser, not as limited as JSON/STON), strings (no escape codes, single quotes needs to be doubled), symbols (can handle more characters than STON symbols), character literals, byte array literals and true/false/nil.\nLiteral arrays are quite nice but they lack the concept of \u0026ldquo;associations\u0026rdquo; and thus no simple readable way to represent a Dictionary. And that is a BIG negative. Funny enough, if we added support for literal dictionaries to Smalltalk then literal arrays would match JSON, with a few extras on the side!\nAmber has recently added support for dynamic literal HashedCollections using this syntax:\n#{'hey'-\u0026gt;12 . aString-\u0026gt;'123123'} It is simply a dynamic {} array (was introduced originally in Squeak I believe) but with the assumption that the expressions all evaluate to Associations that are limited to a string as key. This is because it will be turned into a HashedCollection which is the Amber counter part of a JavaScript object, and JavaScript objects are limited to having strings as keys (Sidenote: Amber also has a generic Dictionary without that limitation).\nWithout a syntax for dictionaries, literal arrays, although nifty and syntactically quite compact, are still limited in expression. And of course, while Smalltalk literals are fairly simple to parse, other languages do not typically know how to do it - and when it comes to numbers, the Smalltalk full range of syntax is perhaps a bit of an overkill if we aim at cross language portability. Having literal syntax for Characters is also clearly of less value, ByteArrays on the other hand are obviously useful.\nSidestory: Adding literal Dictionaries to Smalltalk? Link to heading Smalltalk only evolves in micro steps every other 10 years, but with the current onslaught of Pharo perhaps there is an opportunity to actually take a few more such steps.\nWe will see below that Tirade has added support for \u0026ldquo;-\u0026gt;\u0026rdquo; as a literal syntax instead of being a message send and as I mentioned above Amber has added a special syntax for dynamic Dictionaries, and that was actually done in order to more easily match JavaScript object syntax when interacting with JavaScript.\nSo perhaps the Smalltalk/Pharo community could decide to add literal Dictionaries to Smalltalk using the Amber \u0026ldquo;#{\u0026rdquo; syntax? In such a syntax the separators between Associations can probably not be spaces, it gets confusing to read:\n#{ key -\u0026gt; value key2 -\u0026gt; value2 } A separator is clearly needed and since we use periods generally for that in Smalltalk it\u0026rsquo;s a good choice. Syntactically it could lead people to think it\u0026rsquo;s a dynamic Dictionary, but let\u0026rsquo;s continue the thought experiment. How would it look? As is customary for #() we can ommit the # inside the array:\n#(123 'hey' {key -\u0026gt; value. key2 -\u0026gt; value} 456) It looks fairly nice. However I do admit that we probably should take a long hard look at all our syntaxes and try to bring some harmony to them. Currently, due to legacy, we have literal and dynamic Arrays using #() and {}. A bit unfortunate since we then use both $( and ${ as delimiters for Arrays and make it harder to find good characters for Dictionaries.\nIt would be nice to have a symmetric syntax. Ideally the leading # could indicate \u0026ldquo;literalness\u0026rdquo; - and perhaps we could use another character to indicate dynamic evaluation? Again, just a thought:\n#() - literal Array\n§() - dynamic Array, expressions separated by periods.\n#{} - literal Dictionary, literals separated by periods, support for associations as literals.\n§{} - dynamic Dictionary, expressions separated by periods, associations created as usual using sends.\nYeah, right, how would we ever be able to reach concensus on a leading dynamic character? :) Also, I do think it is wise to syntactically indicate literal vs dynamic, heuristics only lead to developer traps. Better to clearly indicate intention.\nTirade Link to heading Tirade is a format I created for Deltas (ChangeSets improved) and I have written four articles about it earlier . Now, if I would at this point subjectively rank the formats along a few axis it could look like this:\nInteroperability\nJSON: 100% (all languages has it)\nSTON: 70% (one could probably tweak a JSON parser in any language to work)\nLitarrays: 30% (could get higher score if we limit them, a parser would still have to be written)\nTirade: 20% (same problem as with literal arrays, but even more advanced to parse)\nCapability\nTirade: 100% (has the most features and options, by some margin)\nSTON: 60% (second best, still not much better than JSON)\nJSON: 50%\nLitarrays: 40% (severely limited by lack of assocations but has a some features to compensate)\nGrokkability\nJSON: 100% (well documented, we all know it and so does the rest of the world)\nSTON: 90% (rides on JSON)\nLitarrays: 80% (not hard but has quite a few quirks)\nTirade: 70% (more or less as hard as literal arrays, but with a few more concepts added)\nConclusions from the above? Before looking at Tirade I think we can safely say that JSON is a strong choice. STON is IMHO in limbo, I can\u0026rsquo;t see picking it instead of any of the others in a given situation, sorry. Literal arrays could easily become the obvious \u0026ldquo;JSON for Smalltalk\u0026rdquo; if it had associations/literal dictioneris, it sucks for interoperability though.\nTirade on the other hand has associations (on two levels one could even claim) so it can be viewed as \u0026ldquo;JSON++ for Smalltalk\u0026rdquo;. But with more features comes a slightly higher learning curve and a penalty in interoperability. We now have set the scene for the last section about Tirade.\nTirade Link to heading Obviously I am partial, since I created Tirade. But let me try to contrast Tirade to all the others. Note that Tirade was never meant to be interoperable with other languages, it was however designed to be interoperable between different Smalltalk implementations, or at least all Squeak derivatives.\nA stream of messages Link to heading First of all, Tirade is slightly different than the others. They describe a single structure. A valid Tirade \u0026ldquo;document\u0026rdquo; on the other hand, is a series of \u0026ldquo;records\u0026rdquo; terminated by periods. Each such \u0026ldquo;record\u0026rdquo; looks like a Smalltalk message (but without a receiver on the left side), either a unary or a keyword message, like this:\nunaryMessage. key: 'Hello' word: 'world' message: 4711. This high level view as a \u0026ldquo;stream of messages\u0026rdquo; gives us several nice properties:\nThe selector of the Tirade message is a kind of record \u0026ldquo;type\u0026rdquo;. It normally maps to a method on the receiving end that handles this record. That method then knows what to do with the arguments, and thus we don\u0026rsquo;t need to hard code class names into Tirade, like STON does. NOTE: This is not a security problem. There is nothing forcing the parsing end to just blindly perform these messages. In fact, there is nothing forcing the parsing end to be specific at all, it could just be a generic Tirade parser.\nIf we look at a keyword message we realize that it is very similar to a JSON object, it is basically a \u0026ldquo;naked dictionary\u0026rdquo; where each key word is\u0026hellip; right, a key! :) So for simple data we need perhaps not make it more complicated than this.\nIt makes it very easy to extend a Tirade format by simply adding new message selectors that the receiving end can ignore if it wants to.\nSince Tirade is a flow of messages instead of a single, potentially quite large, structure like the other three formats, we can naturally stream it and handle each message one by one.\nAnd since we have this flow we can also use \u0026ldquo;control messages\u0026rdquo; that can instruct the receiving end on how to receive the messages coming next in the flow. One could even use Tirade over a bidirectional link (a SocketStream for example) and do handshaking and client server communication with it.\nFinally, in between Tirade messages one can add Smalltalk style comments which are simply skipped by the parser. JSON and STON has no concept of comments.\nSmalltalk literals Link to heading The next level of Tirade is what kind of arguments we are allowed to put in between the keywords. Basically its most kinds of Smalltalk literals with some additional constructs. I would also like to point out that this part is not encarved in stone, I am still contemplating the best mix of literal support here. But the main point is that we only allow literals - no expressions, so there is no generic \u0026ldquo;eval\u0026rdquo; going on here.\nNotable differences again compared to JSON/STON on the atomic level are just like with literal arrays:\nStrings are Smalltalk strings, no escape codes except for double single quote for single quote.\nNumbers are Smalltalk literal numbers, in fact we rely on the number parser of Pharo/Squeak. This gives us a rich notation for numbers, at the expense of possible portability issues with other Smalltalks.\nNOTE: Tirade doesn\u0026rsquo;t currently implement Character literals nor ByteArrays, both can of course be added.\nLet\u0026rsquo;s continue with the added features for literals.\nLiteral feature: Verbatim strings Link to heading A problem with JSON for dealing with readability is that JSON strings can\u0026rsquo;t have newlines in them! So if you want to store source code in JSON it will end up as a single very long line.\nSmalltalk strings like in Tirade can have newlines in them, but they suffer from double quoting of single quotes and the problem that the single quotes surrounding the string needs to be first on the first line and last on the last line, which makes it less readable.\nThis is why I came up with verbatim strings in Tirade, specifically for being able to contain unmodified source code in a readable way with no escapes whatsoever. I am not sure if this is the best approach, perhaps here-docs would be a simpler approach, but currently a verbatim string looks like this:\nsome: 1 message: 'hey' withVerbatimStringForCode: [ This is untouched, perfectly unescaped source code, ANY character combinations will work! Tirade will split the input on each CR (byte = 13) and then prepend each line with a TAB character. This means that the parser can detect the end by looking for the first line starting with \u0026quot;]\u0026quot;, that must be the end of the verbatim string since all other lines start with TAB. Copy paste will work but you will need to care for the TAB indentation, but most editors can do that easily. Also, right before and after the string there is a newline added to improve readability. ]. Literal feature: Associations Link to heading Since we really want to be able to do dictionaries I first added literal support for Associations. This means \u0026ldquo;-\u0026gt;\u0026rdquo; is a literal syntax for creating an Association, it doesn\u0026rsquo;t need to be in a Dictionary, you can use them wherever you like and the key and value can be ANY literal construct allowed by Tirade, even an Assocation!\nNote though that we do not have parenthesis in Tirade (no expressions at all) and the current Tirade parser is a recursive descent bottom up parser so the code below will produce an Assocation with key #key and value an Association 123-\u0026gt;\u0026lsquo;123\u0026rsquo;. In Smalltalk where #-\u0026gt; is a message this is instead executed from left to right creating a different result.\ncool: #key-\u0026gt;123-\u0026gt;'123'. This also means that Tirade can have associations inside literal arrays, which is not syntactically possible in Squeak/Pharo:\ncool: #(12-\u0026gt;'123'). Finally, since Amber lately added #{} syntax for Dictionaries I think it could be a worthwhile addition to Tirade also.\nLiteral feature: Dynamic arrays as literal Link to heading Tirade supports {} style arrays, but doesn\u0026rsquo;t allow expressions so they are very much like normal arrays except they do not remove #-prefixes from nested arrays/symbols and they look more natural to Squeakers since Squeak allows Association literals inside them:\ncool: {12-\u0026gt;'123. 'banana'-\u0026gt;true}. Is it worth supporting both kinds of arrays? It depends, either Tirade defines a literal subset that is as small as possible, or Tirade tries to cover all literals of Pharo. I was leaning towards a subset but perhaps a super set is more attractive to people.\nEnding thoughts Link to heading I hope this article explained a few things and made at least Tirade a bit clearer. There are several things not fully settled in Tirade and if anyone wants to dig in and tweak it, feel free to email me.\nregards, Göran\n"},{"title":"Going Lenovo...","permalink":"https://goran.krampe.se/2012/04/14/going-lenovo/","summary":"\u003cp\u003eWhen I started my own company about a year ago I ended up buying an \u003ca href=\"http://www.notebookreview.com/default.asp?newsID=5866\u0026amp;review=asus\u0026#43;g73\u0026#43;g73jw\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eASUS G73JW\u003c/a\u003e\n gaming laptop - I took a deliberate decision to focus on raw power for decent money and totally ignoring portability. Generally it has served me well, although it does tend to make a lot of fan noise, at least under Ubuntu. It might work smoother in Windows, but I seldom boot into Windows.\u003c/p\u003e\n\u003cp\u003eNeedless to say though it is a \u003cstrong\u003ereal ton of bricks\u003c/strong\u003e (8.8 lbs = 4 kg) and including the truly fat power supply it simply weared my back down during 2011. I have been carrying this beast in a backpack every day - and my body eventually said \u0026ldquo;enough dammit!\u0026rdquo;. :)\u003c/p\u003e","content":"When I started my own company about a year ago I ended up buying an ASUS G73JW gaming laptop - I took a deliberate decision to focus on raw power for decent money and totally ignoring portability. Generally it has served me well, although it does tend to make a lot of fan noise, at least under Ubuntu. It might work smoother in Windows, but I seldom boot into Windows.\nNeedless to say though it is a real ton of bricks (8.8 lbs = 4 kg) and including the truly fat power supply it simply weared my back down during 2011. I have been carrying this beast in a backpack every day - and my body eventually said \u0026ldquo;enough dammit!\u0026rdquo;. :)\nUltrabook? Link to heading So I decided to upgrade to some hot new hardware weighing below 2 kg and naturally I started looking at the current crop of ultrabooks . And no, Macbook Air is not for me, sorry. After reading lots of reviews my perception is that all of the current Ultrabooks have one problem or another. This may be because of this being the first generation of Ultrabooks in combination with manufacturers pushing the envelope technologically:\nKeyboards tend to be troublesome given the limitations on thickness making the keys too shallow, the Zenbook for example suffers from bad reviews pointing out the fact that you really need to hit the keys in the middle for them to register.\nTouchpads are also an area lacking, probably because most of them are now moving to so called \u0026ldquo;clickpads\u0026rdquo; with integrated buttons.\nScreens tend to be less than stellar.\nThere have also been reports on issues with wifi having bad reception.\nThen of course, a general lack of ports, but that is to be expected in this form factor.\nI was still leaning towards the Lenovo u300s . It seems to be a truly awesome machine with no apparent weakness although they say the screen is not something to write home about. But I simply can not find where to buy one! Reading up on this Lenovo I came across a lot of people proposing the X220 as a better choice. Eventually I started to read up more on the rest of the Lenovo line, especially the X220 and X1 .\nLenovo X220! Link to heading After some serious soul searching I decided that I really need an X220 instead of a shiny ultrabook toy , and today when I was home sick I ordered one from Dustin with home delivery - 2 hours after placing the order a car drove up to the house and delivered it - sweet!\nSo what about the newer X1 then? Well, what did it for me was the weight and size difference combined with the fact that I really wanted the IPS display. I have read some more comparisons afterwards and feel I made the right decision, although the keyboard on the X1 does get rave reviews even compared to X220. This means it must be insanely great since the keyboard is one of the true highlights of the X220.\nAfter just a few hours with the X220 I am certain I made the right choice. This machine is\u0026hellip; well, if Ultrabooks are flashy slim Ferraris and Porsches this machine would be\u0026hellip; a mini Humvee. It is function focus all the way. Here is a list of key arguments for the X220:\nSuperb real keyboard which is a true joy to type on. This is important and a key differentiator for Lenovo in general. It also has the Trackpoint (the little red mouse stick thing), quite nice if you learn to use it - which I am trying right now.\nFull voltage CPUs with top of the line being a Core i7-2640 giving even more power than the low voltage variations found in Ultrabooks.\n8 Gb RAM (two replaceable slots). Many ultrabooks only give you 4 Gb max and non replaceable. For a small additional price I got an extra 4Gb memory module that was trivial to install. In fact, there are people who have managed to install two 8Gb modules giving a maximum of 16Gb!\n1366 x 768 matte IPS panel, same technology as in the Ipad they say. Awesome display and a rarity among laptops. And matte damnit! This is alone a very strong argument for the X220. I mean, this screen rocks! Of course, higher resolution would have been nice but it\u0026rsquo;s fine.\nTons of ports and ways to extend and replace parts (battery, memory, hard drive etc)\n1.3-1.6 kg depending on choice of battery, clearly in Ultrabook class.\nInsane battery life with several battery options! The protruding 9-cell battery I got is meant to give up to 15 hours! There are 4 different battery sizes, just pick and choose. I am going to get an additional 4 or 6-cell variant which doesn\u0026rsquo;t protrude, when I want to be \u0026ldquo;slick\u0026rdquo; :)\nSo it has most Ultrabook properties (real power, lightweight, small form factor, good battery life) although not as slim. But in all other respects it is a true work horse for professionals. And for me weight is what counts, not thickness.\nI guess it boils down a bit to what kind of person you are. I wanted a really good and lightweight laptop that I can work on, but I also wanted something different, as the title of this blog says - I travel the road less taken. And X220 is a true utilitarian beast sending a \u0026ldquo;100% no nonsense\u0026rdquo; message.** **\nPerformance Link to heading Getting acquainted with the machine I decided to run some benchmarks in Windows 7. I downloaded the CrystalDiskMark and while not as good numbers as the best drive in UX31E it still got decent numbers:\nSequential Read : 259.164 MB/s Sequential Write : 170.058 MB/s Random Read 512KB : 172.326 MB/s Random Write 512KB : 169.432 MB/s Random Read 4KB (QD=1) : 17.175 MB/s [ 4193.1 IOPS] Random Write 4KB (QD=1) : 31.436 MB/s [ 7674.9 IOPS] Random Read 4KB (QD=32) : 140.489 MB/s [ 34299.1 IOPS] Random Write 4KB (QD=32) : 95.920 MB/s [ 23418.1 IOPS] But this is of course an attribute of the Intel SSD drive more than the actual notebook. I also downloaded and ran the free PCMark 7 in which it scored 4004. This is better than the fastest Ultrabook (UX31E which got 3653) but I had hoped for even better, perhaps I missed cranking up the speed correctly.\nTo top things off, here is a list of more funky details:\nA small downward directed LED lamp (Thinklight) right beside the web cam that illuminates the keyboard. Hehe, kinda low tech compared to backlit keyboards, but it works. I guess it is hard to make a traditional \u0026ldquo;non chiclet\u0026rdquo; keyboard backlit.\nA 720p HD web cam. Oh. :)\nA fingerprint biometric reader! So now I log on W7 by swiping my index finger, funky.\n54 mm Express Card slot. No idea what to use it for yet!\nOne combined mSATA/PCIe internal slot. In my machine it holds a UMTS 3G card. I just slid in my SIM card and it hooked up nicely!\nThe second half PCIe port. No idea what to use that for either.\nOption to buy an additional mSATA SSD drive (currently available up to about 128Gb) giving even more disk space. Unfortunately this would mean ripping out the UMTS card.\nThe navpoint (red mouse stick) has three buttons below and if you hold the middle button you get scrolling for the navpoint - really nice! Or perhaps obvious, but I like it.\nNegative stuff so far Link to heading Well, these are nitpickings, but still, these are things that have annoyed me a bit:\nAlthough I really like the little red nubbin, it does get in the way when I type \u0026ldquo;b\u0026rdquo; sometimes, my right hand index finger \u0026ldquo;stumbles\u0026rdquo; over it. Might be simply an issue of getting used to the keyboard.\nThe palm rests are very small on this machine due to its size. For my right hand it is not an issue because the red nubbin and touchpad is slightly off to the left so I tend to rest my right palm slightly more to the middle. But my left wrist ends up squarely on the left side corner of the laptop. And while the front edge is sloped downwards to make it comfortable, the sides are not sloped at all.\nThe Ctrl and Fn keys seems swapped for my taste, the Ctrl should IMHO be in the corner. In the BIOS one can swap these (!) but then I would really like to change the writing on the keys too\u0026hellip;\nUPDATE: The nubbin doesn\u0026rsquo;t get in the way anymore, obviously a thing that one \u0026ldquo;learns\u0026rdquo; automatically. I haven\u0026rsquo;t thought about the palm rests since I wrote the article, so it was nitpicking. I haven\u0026rsquo;t swapped the Ctrl-Fn keys, simply learned the layout. Possibly will swap still though.\nSoftware included Link to heading Normally I don\u0026rsquo;t care about installed software but Lenovo has actually included quite a few useful utilities for Windows 7. Power management, biometric finger print management, yaddayadda. This makes it harder to make the decision to wipe Windows.\nHere comes\u0026hellip;. Ubuntu! Link to heading First I tested running Ubuntu in a VirtualBox and while it works quite well it still seems to behave better on the real hardware. This is probably due to the graphics capabilities in VirtualBox. Anyway, one of the main reasons for going with a Thinkpad is also of course the fact that they tend to work really, really well with Linux. And the X220 is not an exception . I have been running Linux as primary OS for almost 6 years now so I really want to continue doing that, but I am being cautious and will go for a dual boot setup for now.\nThese are the basic steps I performed:\nProduce the so called \u0026ldquo;Factory Recovery\u0026rdquo; disks. This takes the recovery partition that Lenovo has put on the SSD and slaps it onto external media so that you can wipe that partition and reclaim about 16Gb of disk space. It\u0026rsquo;s also nice to have, if something goes bonkers.\nShrink the Windows 7 partition thus leaving unpartitioned space for Ubuntu.\nPrepare a USB stick with Ubuntu.\nInstall Ubuntu from the USB stick producing a dual boot setup.\nFunny enough it was the first step that turned out a bit tricky, the rest was a piece of cake.\nProducing Factory Recovery media Link to heading One would think that since everyone should do this it would be trivial to do. If I would design this procedure I would make it possible to produce iso-files that can just be saved onto an USB hard drive, but no no\u0026hellip; :)\nPrepare a USB drive according to this document . It must be either at least 350Mb (only for booting) or about 9Gb (both bootable and recovery data).\nIf you picked a small USB like I did, when you run the utility from Lenovo - only select \u0026ldquo;boot\u0026rdquo; when you get the dialog with two check boxes. It will then wipe the drive and make it bootable, but not put recovery data onto it. Then you can fire up the utility once more and use an USB hard drive for the other checkbox (recovery data), it does not need to be empty because it will not wipe it, it will just create a directory called \u0026ldquo;factoryrecovery\u0026rdquo; and put all data into it.\nIf you picked a large USB stick (or hard drive) then you can select both checkboxes and get it all in one place in one go.\nNOTE: You should try booting from it to see that it actually boots. To do that you will need to enter the BIOS setup (F1 or F12 on boot) and move the USB flash drive higher up in the boot order list. Of course, when this is all done one could produce an iso from that bootable USB stick and store it away somewhere to free up a perfectly good USB stick :)\nThen finally you can let the tool \u0026ldquo;reclaim\u0026rdquo; the partition, it will nuke the paritition and then enlarge the Windows 7 partition with that space, but we will shrink it in the next step.\nShrink Windows Link to heading This is easy in 2012, Windows can do it for you. Just open control panel, type in \u0026ldquo;partition\u0026rdquo; and open the tool that it finds. Select the Windows 7 partition and use \u0026ldquo;shrink\u0026rdquo; in the popup menu. Then you get to a dialog in which you can specify how much you want to shrink it.\nPrepare a USB with Ubuntu Link to heading There are many ways to install Linux and in the older days the traditional way was to burn a CD and boot from it into the installation procedure. These days I guess the most common procedure is to do the same, but with a USB stick. In retrospect the Wubi installer might have been even easier, but I wanted to install the beta 2 of Ubuntu \u0026ldquo;Precise Pangolin\u0026rdquo; and didn\u0026rsquo;t think Wubi was up to date with that, but it seems you can download any iso you want on the side for it.\nAnyway, I downloaded Unetbootin and the Pangolin beta 2 iso and then \u0026ldquo;burned\u0026rdquo; it with Unetbootin to a USB stick. Done.\nInstall Ubuntu Link to heading Well, what can I say? Just boot from the stick and go with the flow. The installer is trivially easy, it will detect the existing Windows 7 and even offers to import bookmarks and stuff from your Windows user! A dual boot setup is produced without questions asked even, it was simple as that.\nConclusion Link to heading I love this machine! And the only thing not working perfectly smooth in Ubuntu is the 3G, it fails to unlock when I give the PIN code, not sure why. Also, one will need to do some tweaking to get less battery drain in Linux, but I think the forums indicate that it is possible to get similar results as in Windows.\nSo take my advice - if you are looking at the Ultrabooks, do take a long look at the X220 before making your decision. :)\nUPDATE: The 3G card actually works perfectly, the failure to unlock was just a glitch. Also, now there is X230 which seems to be an upgraded X220 but with the new backlit chiclet-keyboard instead. Good move Lenovo, although I honestly don\u0026rsquo;t know if I would pick it in favor of the \u0026ldquo;real old-fashioned\u0026rdquo; keyboard of X220.\n"},{"title":"Current Smalltalk obsessions...","permalink":"https://goran.krampe.se/2012/02/07/current-smalltalk-obsessions/","summary":"\u003cp\u003eThese days I am, as usual, torn between several interesting technical projects.\u003c/p\u003e\n\u003ch1 id=\"amber\"\u003e\n  Amber\n  \u003ca class=\"heading-link\" href=\"#amber\"\u003e\n    \u003ci class=\"fa-solid fa-link\" aria-hidden=\"true\" title=\"Link to heading\"\u003e\u003c/i\u003e\n    \u003cspan class=\"sr-only\"\u003eLink to heading\u003c/span\u003e\n  \u003c/a\u003e\n\u003c/h1\u003e\n\u003cp\u003eThe new \u003ca href=\"http://www.world.st\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSmalltalk\u003c/a\u003e\n called \u003ca href=\"http://www.amber-lang.net\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eAmber\u003c/a\u003e\n (by Nicolas Petton) that compiles to javascript is pretty awesome and there are tons of interesting things one can do with it. My contributions so far include the beginning of a package model, a faster simpler chunk format exporter/importer, a command line compiler, a Makefile system so that Amber can be built fully from the command line and a bunch of \u003ca href=\"https://github.com/NicolasPetton/amber/tree/master/examples\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eexamples\u003c/a\u003e\n running on top of \u003ca href=\"http://nodejs.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNodejs\u003c/a\u003e\n and \u003ca href=\"http://developer.palm.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ewebOS\u003c/a\u003e\n, and a few other odds and ends.\u003c/p\u003e","content":"These days I am, as usual, torn between several interesting technical projects.\nAmber Link to heading The new Smalltalk called Amber (by Nicolas Petton) that compiles to javascript is pretty awesome and there are tons of interesting things one can do with it. My contributions so far include the beginning of a package model, a faster simpler chunk format exporter/importer, a command line compiler, a Makefile system so that Amber can be built fully from the command line and a bunch of examples running on top of Nodejs and webOS , and a few other odds and ends.\nI would like to port Deltas to Amber in order to create a powerful toolset for managing code changes. Using local storage it would among other things enable undo and change logging to prevent accidental code loss. It could also easily form the basis for a \u0026ldquo;commit tool\u0026rdquo;, similar functionality that git stash offers etc.\nAnother thing I would like to build is a dead simple public shared package repository. And play with Socket.IO , or just fool around with the compiler trying to add optimizations like various type inferencing, optimizing self and super sends etc :). So much fun stuff to do!\nSTOMP and Apollo Link to heading For a personal \u0026ldquo;secret project X\u0026rdquo; I need scalability so it is being designed with lots of daemons each taking care of a specific task. I want to be able to implement these daemons primarily in either Nodejs (in plain js or using Amber) or Pharo Smalltalk , but also in any other language that fits.\nThis requires some kind of messaging infrastructure to tie them together. So\u0026hellip; after looking hard and long and reading a lot about messaging, job scheduling, AMQP , 0MQ , STOMP , Beanstalkd , RabbitMQ , ActiveMQ Apollo (and tons of other things) I decided to try to use the new ActiveMQ Apollo together with STOMP 1.1 (which should also be supported by the STOMP plugin for RabbitMQ etc).\nThe new Apollo implementation is written in Scala using HawtDispatch so the architecture seems modern and the JVM of course has very good performance these days. So, while I generally am very tired of Java and its eco system, this actually seems like a solid product and has already shown very impressive numbers in benchmarks .\nSo a sound asynchronous architecture with good performance is nice but the other thing I like with ActiveMQ is their focus on STOMP. Since I intend to use Pharo as one major component I need to be able to hook it into the messaging backbone. And sure, Tony Garnock Jones - one of the main developer behind RabbitMQ - actually has an AMQP client library written for Squeak 3.9, so I could probably us AMQP, but I somehow foresee a \u0026ldquo;world of hurt\u0026rdquo; in the complexity given that AMQP is a magnitude more complex than STOMP.\nI have already implemented STOMP 1.0 for Pharo , actually tried it with RabbitMQ at the time, so I am now upgrading that library to work with 1.1 of the specification.\nRiak Link to heading The other important piece of the puzzle for true \u0026ldquo;Internet scalability\u0026rdquo; is of course the choice of persistence. I am a long time fan of the new NoSQL databases and having played with a few of them, implemented a C# binding for CouchDB, hacked some bindings in Squeak for both CouchDB and Tokyo Tyrant\u0026hellip; I now have decided to focus on Riak . Riak is IMHO the most interesting NoSQL database out there right now, at least for worry free ultra scaling. Sure, it may not be the fastest on a single box - but if you are really serious about scaling - one box is totally uninteresting. :)\nRunar Jordahl had already started a Riak binding in Pharo, I took it and changed quite a lot of it - not really because it was \u0026ldquo;bad\u0026rdquo; or anything, I just have a different style of coding I guess. So I decided to fork because I didn\u0026rsquo;t feel comfortable - thus Phriak was born . Now Nicolas Petton is getting hard into Riak too and has pushed Phriak forward quite a LOT in the last few days, much further than I had time to do. It now has a clean command style protocol implementation, an object model similar to the one in Ripple (Ruby Riak client) and initial working code for both secondary indexing, link walking and map/reduce! Quite impressive stuff.\nNicolas is also experimenting with writing an \u0026ldquo;OODB-ish\u0026rdquo; database using Fuel called Oak and after I managed to get him hooked on Riak he has been moving that codebase over onto Phriak. The initial experience we have with Phriak and Oak is extremely promising and who knows where this will lead.\nHappy coding, Göran\n"},{"title":"ESUG day 4","permalink":"https://goran.krampe.se/2011/08/25/esug-day-4/","summary":"\u003cp\u003eThis day started with some stress, Nicolas and I whipped up the last details of our co-presentation on \u003ca href=\"Http://jtalk-project.org\" \u003eJtalk\u003c/a\u003e\n (Nicolas decided to skip \u003ca href=\"Http://www.iliadproject.org\" \u003eIliad\u003c/a\u003e\n) - and my Eris demo suddenly got b0rken. But I managed to fix it and our presentation was \u003cstrong\u003every well\u003c/strong\u003e received - it was great fun!\u003c/p\u003e\n\u003cp\u003eNicolas managed to do quite a few \u0026ldquo;on the fly\u0026rdquo; demonstrations of various Jtalk snippets etc, and running \u003ca href=\"Http://nicolas-petton.fr/presentations/esug2011\" \u003ethe slides\u003c/a\u003e\n in Jtalk was of course a killer thing. I explained how jtalkc is being run on top of Node.js and quickly proceeded into showing the \u003ca href=\"Http://github.com/gokr/jtalk/tree/master/nodejs/trivialserver\" \u003eTrivialServer\u003c/a\u003e\n demo in Node.is - when Apache benchmark showed \u003cstrong\u003e1800 requests/second\u003c/strong\u003e there was a spontaneous applause. :)\u003c/p\u003e","content":"This day started with some stress, Nicolas and I whipped up the last details of our co-presentation on Jtalk (Nicolas decided to skip Iliad ) - and my Eris demo suddenly got b0rken. But I managed to fix it and our presentation was very well received - it was great fun!\nNicolas managed to do quite a few \u0026ldquo;on the fly\u0026rdquo; demonstrations of various Jtalk snippets etc, and running the slides in Jtalk was of course a killer thing. I explained how jtalkc is being run on top of Node.js and quickly proceeded into showing the TrivialServer demo in Node.is - when Apache benchmark showed 1800 requests/second there was a spontaneous applause. :)\nNow we can relax and talk to all people about Jtalk - and now in fact the web panel starts with Nicolas on the panel. Unfortunately the panel discussion didn\u0026rsquo;t play out that well, it needs some entertainment and also at least one or two that disagree :)\nLater tonight and tomorrow we will probably keep on hacking Jtalk like mad. So much fun stuff to play with! We intend to \u0026ldquo;finish\u0026rdquo; the first stab at so called \u0026ldquo;speculative inviting\u0026rdquo; that we started earlier this week, and try to do some profiling on it to verify the gains. Using the Compiler is actually a good candidate for a reasonable benchmark.\nThe evening ended with the usual pubs and hacking and chatting about cool things people are doing.\n"},{"title":"ESUG day 3","permalink":"https://goran.krampe.se/2011/08/24/esug-day-3/","summary":"\u003cp\u003eSuddenly it is Wednesday and we are already on day three at \u003ca href=\"Http://www.esug.org\" \u003eESUG\u003c/a\u003e\n - a superb software developer conference focused on \u003ca href=\"http://www.world.st\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSmalltalk\u003c/a\u003e\n. Time flies. Yesterday I mainly hacked together with Nicolas Petton on \u003ca href=\"Http://www.jtalk-project.org\" \u003eJtalk\u003c/a\u003e\n, really fun, unfortunately I missed a few interesting presentations, like Fuel and Bifrost etc.\u003c/p\u003e\n\u003cp\u003eThis day starts with Stéphane presenting \u0026ldquo;Humane assessment\u0026rdquo;. Mmm, got distracted by my Touchpad, but Stéphane is showing some cool visualizations right now, clearly useful for large systems and organisations that need understand their own \u0026ldquo;huge legacy software\u0026rdquo;. Hehe, the browsers shows visual queues on \u0026ldquo;bad designs\u0026rdquo; like marking methods as \u0026ldquo;BrainMethod\u0026rdquo; or marking a class as \u0026ldquo;God Class\u0026rdquo; - that is indeed very slick!\u003c/p\u003e","content":"Suddenly it is Wednesday and we are already on day three at ESUG - a superb software developer conference focused on Smalltalk . Time flies. Yesterday I mainly hacked together with Nicolas Petton on Jtalk , really fun, unfortunately I missed a few interesting presentations, like Fuel and Bifrost etc.\nThis day starts with Stéphane presenting \u0026ldquo;Humane assessment\u0026rdquo;. Mmm, got distracted by my Touchpad, but Stéphane is showing some cool visualizations right now, clearly useful for large systems and organisations that need understand their own \u0026ldquo;huge legacy software\u0026rdquo;. Hehe, the browsers shows visual queues on \u0026ldquo;bad designs\u0026rdquo; like marking methods as \u0026ldquo;BrainMethod\u0026rdquo; or marking a class as \u0026ldquo;God Class\u0026rdquo; - that is indeed very slick!\nAll in all it looks like a very useful tool - I should probably try it out on some codebase. In fact, this tool is a really good \u0026ldquo;added value\u0026rdquo; tool that can be offered to customers when helping them. I have at least one client that really could make some good use of a tool like this.\nNext up before coffee is Arden Thomas from Cincom (hehe, that was funny, the Touchpad wanted to correct \u0026ldquo;Cincom\u0026rdquo; to \u0026ldquo;Condom\u0026rdquo;\u0026hellip;) presenting what is new in their products / ObjectStudio and VisualWorks. These are really mature and amazing Smalltalk tools, but of course they also costs money, money, money. But VisualWorks is accessible in a non commercial full version, which is quite nice if it fits your needs. Cincom is also quite active in a bunch of open source Smalltalk projects like for example GLORP (think \u0026ldquo;Hibernate\u0026rdquo; for all you non-Smalltalkers) and Seaside (the most outstanding web framework in the world).\nAfter running around flaunting the Touchpad :) - I came slightly late to Igor Stasenko\u0026rsquo;s presentation on NativeBoost . I have worked with Igor and he has this refreshing \u0026ldquo;fearlessness\u0026rdquo; so diving into assembler is not a problem for him. So NativeBoost is an extension to the Squeak VM (and the new Cog VM) that enables dynamic machine code generation - and execution - directly from Smalltalk using just Smalltalk. So it includes a DSL for writing assembler (a port of AsmJit ) and mechanisms to access memory etc etc. The machine code needs to be relocation agnostic since it is actually stored directly in a Smalltalk object (the method) and will be moving around due to the garbage collector moving things around. Another interesting issue is that if the machine code calls into the VM in order to create a Smalltalk object, it will need to be aware of the fact that this can trigger GCs and move things around - but this is just the same for building VM plugins. Of course, Igor\u0026rsquo;s stuff is very impressive and you can make very fast code using it.\nThe day then ended with the social event and announcing the winners of the awards and a nice dinner followed up with some beer and endless \u0026ldquo;Why doesn\u0026rsquo;t everyone use Smalltalk?\u0026rdquo; discussions - as is customary.\nOver and out, Goran \u0026ldquo;typing this in on my Touchpad using the bluetooth keyboard\u0026rdquo;\n"},{"title":"Touchpad finally in my hands, first day","permalink":"https://goran.krampe.se/2011/08/23/touchpad-finally-in-my-hands-first-day/","summary":"\u003cp\u003eSooo\u0026hellip;. I actually managed to order a HP Touchpad 32Gb here in Edinburgh to be picked up at Comet within 48 hours. I ordered when it was still a whopping 429£, but when I went to pick it up I got it at the UK \u003cstrong\u003ediscount price of 115\u003c/strong\u003e, and I will get the VAT back too.\u003c/p\u003e\n\u003cp\u003eThe first hours were frustrating because I was in the ESUG conference and we only had a WiFi with a so called \u0026ldquo;captive portal\u0026rdquo; with a login form - and the first time you power up a Touchpad it wants to hook up to a Palm Profile, and does not want to do that using a WiFi with a captive portal.\u003c/p\u003e","content":"Sooo\u0026hellip;. I actually managed to order a HP Touchpad 32Gb here in Edinburgh to be picked up at Comet within 48 hours. I ordered when it was still a whopping 429£, but when I went to pick it up I got it at the UK discount price of 115, and I will get the VAT back too.\nThe first hours were frustrating because I was in the ESUG conference and we only had a WiFi with a so called \u0026ldquo;captive portal\u0026rdquo; with a login form - and the first time you power up a Touchpad it wants to hook up to a Palm Profile, and does not want to do that using a WiFi with a captive portal.\nThe Montague pub to the rescue later that evening, an open wifi. I am currently writing this post using the Bluetooth keyboard (so nice) while the TP is snugly positioned on the Touchstone inductive charger. Both these are great accessories. I have also managed to do Skype with my wife, really easy and worked well, hook up the calendar to Google with perfect sync, and in fact it synched over all my contacts etc from my Palm Profile for my Palm Pre 2 - just works!\nI have done the OTA 3.0.2 update (in the pub while eating) and I have installed a bunch of apps, like the one I am typing in know - for WordPress. I have also activated the included 50Gb free cloud space included from box.net - brilliant.\nEmail app is running fine, Facebook app is very good, tons of other little nifty things - I am a happy camper! Is it just as \u0026ldquo;smooth as silk\u0026rdquo; as the iPad? No, but it excels in other areas like true multitasking, a real Linux beneath (bonus for me as a developer), synergy, full flash, 50Gb cloudspace for life included, really good virtual keyboard (multiple sizes even) etc etc. Sure, slightly thicker and slightly heavier - but\u0026hellip;. BUT\u0026hellip;. It cost me around 85£ with 32Gb RAM. That argument is a killer.\nDay after tomorrow I will be demonstrating apps written in Jtalk running on it - yiha!\n"},{"title":"ESUG 2011 in Edinburgh","permalink":"https://goran.krampe.se/2011/08/11/esug-2011-in-edinburgh/","summary":"\u003cp\u003eEach year I try to attend at least one developer conference. Earlier OOPSLA was a given but it lost its appeal quite a few years back and now it is not even called OOPSLA anymore. As a die hard \u003ca href=\"http://www.world.st\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSmalltalker\u003c/a\u003e\n I instead attended the \u003ca href=\"http://www.esug.org/wiki/pier/Conferences\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eESUG conference\u003c/a\u003e\n in Brest 2009 and it was easily the most rewarding conference I ever have attended! Missed last year in Barcelona but this year I am going to \u003ca href=\"http://www.esug.org/wiki/pier/Conferences/2011\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eEdinburgh\u003c/a\u003e\n for a week of Smalltalking.\u003c/p\u003e","content":"Each year I try to attend at least one developer conference. Earlier OOPSLA was a given but it lost its appeal quite a few years back and now it is not even called OOPSLA anymore. As a die hard Smalltalker I instead attended the ESUG conference in Brest 2009 and it was easily the most rewarding conference I ever have attended! Missed last year in Barcelona but this year I am going to Edinburgh for a week of Smalltalking.\nI am not presenting anything but I hope I will get my HP Touchpad from Amazon before it starts so that I can demonstrate a WebOS app running on it written in Jtalk .\nIf you are going too, see you there!\n"},{"title":"WebOS 3.0 is coming - with Enyo!","permalink":"https://goran.krampe.se/2011/07/09/webos-3-0-is-coming-with-enyo/","summary":"\u003cp\u003eA few weeks ago I joined the Early Access program that HP/Palm has been offering for a while and I have been toying with the new \u003ca href=\"http://developer.palm.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eWebOS 3.0\u003c/a\u003e\n (SDK with emulator) that appeared in public on the 1st of july when the \u003ca href=\"http://www.hpwebos.com/us/products/pads/touchpad/index.html\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eHP Touchpads\u003c/a\u003e\n hit the stores in the US. Since a week I also have a \u003ca href=\"http://www.hpwebos.com/us/products/phones/pre2/index.html\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ePalm Pre 2\u003c/a\u003e\n phone running WebOS 2.1, hopefully to be upgraded later to 3.0.\u003c/p\u003e","content":"A few weeks ago I joined the Early Access program that HP/Palm has been offering for a while and I have been toying with the new WebOS 3.0 (SDK with emulator) that appeared in public on the 1st of july when the HP Touchpads hit the stores in the US. Since a week I also have a Palm Pre 2 phone running WebOS 2.1, hopefully to be upgraded later to 3.0.\nWhat can I say, I am totally hooked! The SDK for WebOS 3.0 looks really nice and the Palm Pre 2 is the best phone I have ever used, if I disregard the poor battery life.\nNo, I have never owned an iPhone but my previous phone was the Samsung Galaxy, and that is a really good phone! :) Now, of course, getting the Pre 3 would be even better.\nScreenshots Link to heading ## WebOS Link to heading Having used the phone for a week or two some things stand out:\nThe gesture and cards system for multitasking is a real joy to use. Hard to describe, should be experienced.\nNotifications are really nicely done , non intrusive and slick.\nThe \u0026ldquo;just type\u0026rdquo; mechanism is awesome, typing in a name or a website or whatever - and WebOS will suggest and list \u0026ldquo;everything\u0026rdquo;. And even better, WebOS discovers new \u0026ldquo;search engines\u0026rdquo; when I surf and offer to include them in quick list for searching! Simple and so smart.\nSynergy - the system merging all contact information together is amazingly good, much better than on my Android phone. It merges and syncs info from my LinkedIn, Facebook and Google accounts (and many other sources) brilliantly.\nMessaging is uniform, I can SMS or Gtalk or whatever in the same threaded view for a given contact. Yay!\nAnd there is lots more of these little things, adding up to a very smooth user experience.\nApplication frameworks Link to heading One of the primary new things in WebOS 3.0 (vs 2.x) is Enyo - the new application framework in Javascript that is replacing Mojo, the older framework. Enyo looks like a really well designed object oriented UI toolkit. It focuses on using code and not HTML to produce the user interface and the API looks nice, well documented with examples and quite complete!\nApplications for WebOS 3.0 come basically in three flavors - Enyo/Javascript, OpenGL/SDL/C/C++, or hybrid.\nAn Enyo app is \u0026ldquo;just\u0026rdquo; Javascript running in V8 + Webkit and will be the framework that the majority of the applications will use. Given the push in Javascript land these days I would say it is a very interesting platform.\nMore demanding graphical apps, especially games, can be written in the C/C++ tool chain and use the OpenGL ES and SDL APIs. This seems to be a very friendly platform for game development.\nHybrid apps are Enyo apps (or Mojo) that can embed native components written in the C/C++ tool chain and allow them to render parts of the screen and also communicate with them. This is clearly an interesting option for many demanding apps.\nAn open eco system Link to heading Although WebOS is not open source it seems in many ways more \u0026ldquo;open\u0026rdquo; than the competition:\nIt is trivial to get \u0026ldquo;root\u0026rdquo; on the devices. Just type in \u0026ldquo;upupdowndownleftrightleftrightbastart \u0026rdquo; and click the icon that appears!\nHP/Palm seems to realize that the homebrew community is very important and this community is exceptionally strong .\nUsing the Preware homebrew app catalog and installing themes, patches, applications and more is just as easy and smooth as the regular app catalog (no, you can\u0026rsquo;t browse it on the web, only on a device)!\nThe OS is a real Linux at the base! In fact, the ipk package format for apps is the deb format.\nThe base technologies used are major open source projects like Webkit, V8, SDL, GStreamer etc etc.\nHP is offering a multitude of distribution channels including a \u0026ldquo;web distribution\u0026rdquo; channel where you can market your own app outside of the regular app catalog - but people can still just click on a URL and buy/install the application! That is very nice.\n\u0026hellip;and there are many more aspects to this \u0026ldquo;openness\u0026rdquo;, but I think HP realize that they need to play this part of the game quite a bit better than the competition in order to be able to catch up.\nHigh hopes Link to heading I think HP has a diamond here in WebOS and if they play their cards right they should be able to find their piece of the market share. And that share just needs to be \u0026ldquo;descent\u0026rdquo; in order to be fruitful. But in order for that to happen I am hoping that:\nThe products (Touchpad, Pre 3, Veer) really hit the stores all over the world ASAP.\nThe 3G/4G versions of the Touchpad will show up soon. Just wifi is not enough.\nThe next generation of products keep up with the competition in hardware specs.\nThe major apps people want and need start appearing.\nThe first three are primarily up to HP. The fourth is hopefully not a problem since the eco system is so appealing to developers. And I think HP is trying to make sure some crucial apps are not missing - for example, I think HP made sure the Facebook app is there - and it is indeed a really good app!\nNext up? Well of course, using Smalltalk to build Enyo applications\u0026hellip; :)\n"},{"title":"Konsten att måla ett drev, del 2","permalink":"https://goran.krampe.se/2011/05/17/konsten-att-mala-ett-drev-del-2/","summary":"\u003cp\u003eDags för andra delen i artikelserien om att måla ett drev. \u003ca href=\"http://goran.krampe.se/2011/05/01/konsten-att-mala-ett-drev-del-1/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eFörsta delen\u003c/a\u003e\n avhandlade mest teori om målningsprocessen. Nu är det dags för avmontering av drevet från skölden samt applicering av färgstripper.\u003c/p\u003e\n\u003ch2 id=\"demontering\"\u003e\n  Demontering\n  \u003ca class=\"heading-link\" href=\"#demontering\"\u003e\n    \u003ci class=\"fa-solid fa-link\" aria-hidden=\"true\" title=\"Link to heading\"\u003e\u003c/i\u003e\n    \u003cspan class=\"sr-only\"\u003eLink to heading\u003c/span\u003e\n  \u003c/a\u003e\n\u003c/h2\u003e\n\u003cp\u003eDags att börja meka. Min ambition är att komma åt det mesta av drevets delar utan att gå så långt som att plocka isär det i alla sina beståndsdelar. Köpte Selocs manual - \u003cstrong\u003e\u0026ldquo;Volvo Penta Stern Drives 1992-2002 Repair Manual\u0026rdquo;\u003c/strong\u003e - från \u003ca href=\"http://www.drev.se\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ewww.drev.se\u003c/a\u003e\n (finns en från Clymer också, vet ej vilken som är bäst) och följer instruktionen för att plocka av drevet.\u003c/p\u003e","content":"Dags för andra delen i artikelserien om att måla ett drev. Första delen avhandlade mest teori om målningsprocessen. Nu är det dags för avmontering av drevet från skölden samt applicering av färgstripper.\nDemontering Link to heading Dags att börja meka. Min ambition är att komma åt det mesta av drevets delar utan att gå så långt som att plocka isär det i alla sina beståndsdelar. Köpte Selocs manual - \u0026ldquo;Volvo Penta Stern Drives 1992-2002 Repair Manual\u0026rdquo; - från www.drev.se (finns en från Clymer också, vet ej vilken som är bäst) och följer instruktionen för att plocka av drevet.\nDet första man noterar är att den lyftögla som man ska använda i oljestickans hål för att enkelt kunna hänga upp drevet inte går att köpa hos min Volvo Penta dealer . De berättar att de tillverkat egna sådana öglor! Ok, det ska alltså vara en lyftögla med tumgänga, 1/2\u0026quot;. Kollar med en rad järnaffärer och handlar till slut hos Stockholms expertbutik - Sifvert . Där plockar jag med lite hjälp ihop en lös ögla + en stoppskruv och landar på 150:-. På vägen hem trillar jag in på Jula och tror knappt mina ögon när de faktiskt har en enda sorts lyftögla - precis en sådan jag vill ha! För 29:-, ok.\nMed öglan iskruvad och en provisorisk stång monterad över båtens akter kan jag skrida till verket med avmonteringen av drevet vilket visar sig vara en relativt enkel operation. Kåpan har jag ju tagit av tidigare, tre enkla muttrar så att man kommer åt växelmekanismen. (Grattis Finland, ni tog precis VM-guldet!) Momenten i översikt:\nPlocka loss trimstängerna från drevet.\nPlocka loss växelvajern från växelmekanismen.\nPlocka loss de sex låsmuttrarna som håller drevet och dra ut drevet från skölden.\nVad gäller trimstängerna så varnade varvet för att låsringarna kan gå sönder när man knackar av/på dem, och de kostar 50:- styck! Mina höll dock, men jag var försiktig. Därefter fick jag tålmodigt knacka axeln rakt igenom drevet ut till andra sidan, använde ett armeringsjärn för att kunna knacka vidare när den försvann in i hålet. Seloc säger att man ska använda gummiklubba, men hade ingen sådan :)\nVäxelvajern var också lätt att plocka bort - tricket här är nog att dokumentera väl hur den var monterad. Jag räknade varven som låskuben var påskruvad på vajern, och tog lite foton! När man lossat vajern är det dags att lossa dess infästning på baksidan. När skruven är lös kan man dra ut låsblecket åt sidan så att vajern går att dra ut. På bilden ser man att blecket är utdraget cirka 1 cm och man ser också skåran i växelvajerns plasthölje som blecket var instucket i.\nDags att göra den stora manövern. Lossar de sex muttrarna och när jag försöker få loss den sjätte börjar tappen att snurra! Blir lite stressad eftersom jag inte förstår hur jag nu ska göra - men det visar sig att det bara är att skruva vidare, hela skruven kommer ut istället, puh! När alla sex är borta tar jag tag i drevet och rycker ut det sakta men säkert, ta emot drevaxeln bara så att den inte trillar ner och får sig en smäll. När drevet väl hänger kan jag känna efter hur tungt det är och visst, tungt är det men jag orkar lyfta det så inte så svårt att hantera ensam.\nVärt att notera är de nästan helt bortrostade fästena för plastskydden på sidorna om drevet, samt saltavlagringarna väl synliga i huset. Där är det också en del korrosion faktiskt, ska se ifall man kan kromatera lite där. Det viktigaste - knuten - ser dock väldigt bra ut :)\nFör att senare kunna rengöra och måla delarna av drevet som sitter kvar på båten vill jag i alla fall få bort det yttre \u0026ldquo;huset\u0026rdquo; för att komma åt bättre. Läste om en annan kille i USA som plockat isär sitt drev och plastblästrat det - men jag orkar nog inte gå lika långt som han gick för att ta loss \u0026ldquo;gimbal ring\u0026rdquo; osv, det verkar krävas en del specialverktyg också.\nBörjar med att lossa bälgarna, den övre är enkel att \u0026ldquo;trycka in\u0026rdquo;. Med hjälp av en stor skruvmejsel bänder man enkelt den över halskanten. Den under avgasbälgen är svårare - här behöver man verkligen en sk \u0026ldquo;inre ringtång\u0026rdquo; för att ta tag och få loss den inre metallringen som säkrar bälgen runt halsen. Åter ett inköp på Jula. Manualen tipsar om att vara försiktig för den kan sprätta iväg ordentligt ifall man tappar ringen.\nDärefter ska vi skruva loss de två feta \u0026ldquo;bultarna\u0026rdquo; på sidorna, eh\u0026hellip; ok. Seloc säger att jag ska använda en 1/2\u0026quot; hex drive with a ratchet. Ehum, ok? Efter lite förvirring kring metriska insexnycklar (som tyvärr nästan passar) inser jag att det jag måste ha är alltså en halvtums insexhylsa, dvs insexnyckel för montering på hylsnyckeldragare. Problemet är att de flesta vanliga L-formade insexnyckelsatser i tum, inklusive den jag redan har, stannar precis på storleken innan, dvs 3/8\u0026quot;. Jula verkade inte ha något och inte heller en Claes Ohlson jag sprang förbi. Till slut hittar jag en lös insexhylsa hos TOOLS i Täby - tack, tack! Men mer om det i nästa artikel, nu går vi vidare med att försöka strippa drevet\u0026hellip;\nFedEx levererar Link to heading Som jag nämnde i förra artikeln beställde jag fyra spännande kemikalier från www.chemical-supermarket.com :\nEFS 2500 , färgstripper.\nMetalprep 79 , metallpreparationsvätska.\nT5900 TCP , kromateringsvätska.\nStratocoat Green Epoxy primer , superprimer.\nAllt levererades prydligt inslaget och nu har det blivit dags att se ifall strippern är så otrolig som den verkar ! Jag börjar med att använda Henkels Degreaser som jag köpt på Seasea, enklast att hälla över i en vanlig sprayflaska, spraya och torka av med en gammal T-shirt som trasa (luddar ej).\nDärefter tar jag och häller upp strippern i en liten mugg och penslar på med en vanlig pensel. Använder gummihandskar men denna vätska känns inte alls \u0026ldquo;farlig\u0026rdquo; att hantera, som tapetklister egentligen. Tyvärr är temperaturen relativt låg, kanske 17 grader som mest på dagen. Helst ska det vara 25-29 grader varmt, men det ska fungera i låga temperaturer men då kan det ta flera dagar tills det är helt klart. Penslar hela drevet överallt där jag kommer åt, har vid detta laget bestämt mig för att göra \u0026ldquo;rent hus\u0026rdquo;.\nSlår därefter in hela drevet i en sopsäck eftersom det är risk för regn. Efter några timmar ser man hur färgen \u0026ldquo;bubblar upp\u0026rdquo;, både delar av lacken och självklart också resterna av den hårda Triluxen som bubblar upp bara inom någon timme, den färgen är ju inte alls lika hård som själva lacken.\nBlir otroligt spännande att se ifall det blir så rent som det ser ut på hemsidan! Ifall allt går enligt plan ska jag kunna blåsa av flagorna med högtryckstvätten eller skrubba bort med en grov tvättsvamp.\n"},{"title":"Konsten att måla ett drev, del 1","permalink":"https://goran.krampe.se/2011/05/01/konsten-att-mala-ett-drev-del-1/","summary":"\u003cp\u003eVi som kör inombordare i våra båtar har typiskt drev från Volvo Penta eller Mercruiser. Dreven är av aluminium, eller typiskt någon sorts aluminiumlegering och att måla aluminium är en tekniskt sett mycket intressant process och de flesta som gjort detta kan säkert vittna om att det inte funkar så bra, färgen lossnar helt enkelt efter ett tag. Det verkar gått så långt att många helt enkelt inte ens bryr sig om att försöka bygga upp en korrekt målning utan istället slänger på lite primer och antifouling direkt på aluminiumet och får göra om samma visa efter nåt år!\u003c/p\u003e","content":"Vi som kör inombordare i våra båtar har typiskt drev från Volvo Penta eller Mercruiser. Dreven är av aluminium, eller typiskt någon sorts aluminiumlegering och att måla aluminium är en tekniskt sett mycket intressant process och de flesta som gjort detta kan säkert vittna om att det inte funkar så bra, färgen lossnar helt enkelt efter ett tag. Det verkar gått så långt att många helt enkelt inte ens bryr sig om att försöka bygga upp en korrekt målning utan istället slänger på lite primer och antifouling direkt på aluminiumet och får göra om samma visa efter nåt år!\nIfall du frågar ditt lokala båtvarv, din färgaffär, din billackeringsfirma eller kanske din marinbutik så tror du att de borde veta hur man gör detta på bästa sätt, eller hur? Men det är inte alls troligt! I alla fall inte enligt mina erfarenheter när jag gjorde just detta.\nMitt drev - ett Volvo Penta DP-SM drev från 1998-99 - hade råkat ut för en hel del ytkorrosion, antagligen under föregående ägares sista säsong med landström på bryggan (ajajaj). Det märktes dock inte eftersom hela drevet var målat i svart Trilux-färg (vilket i sig känns lite knepigt - visst, koppartiocyanat, men ändå\u0026hellip;), men när jag började skrapa så slutade det med att jag fick slipa ner drevet till aluminium på kanske 30% av ytan! Ja, båda anoderna var ordentligt slut, på bara en säsong.\nOBS! Slipa bara med aluminiumoxid-papper, icke metalliska saker eller sand. Absolut inte stålborste (om den inte är av rostfritt stål) eller stålull, dessa släpper ifrån sig stål in i aluminiumytan och det kommer sedan att rosta som attans. Jag använde tyvärr en stålborste på borrmaskin (osäker på vad den är av, men knappast rostfri) och har försökt slipa ytterligare för att bli av med det, osäker på om det lyckas.\nNörd som jag är så ville jag veta hur Volvo Penta anser att man bör lacka upp ett drev från grunden och lyckades till slut få tag på verkstadshandboken på nätet för detta drev. Värt att notera i detta sammanhang är att boken för min motor från 1998 (V8 5.7GS) har gamla instruktioner och den lite nyare handboken för 5.7Gi etc har uppdaterade instruktioner för målning av DP-S/SX-drev!\nJag utgår ifrån att Volvo Penta insåg att de behövde justera råden eftersom DP-S/SX-dreven är gjutna i en kisel-aluminiumlegerin. Har ej bekräftat detta med Volvo Penta, men en annan teori kan ju vara att de ändrade tillverkningsprocessen av SX/DP-S efter några år, men det verkar osannolikt. Tacksam ifall någon kan bringa klarhet i detta.\nHur som helst, följande text återfinns i verkstadshandboken (tror inte Volvo Penta blir arga ifall jag återger den här):\nRemove all marine growth. Remove all loose paint and corrosion by sanding or sandblasting. If sandblasting, use an aluminum oxide blasting media with a particulate size of 0.008-0.028 in. (0.2-0.7 mm).\nRemove all trace of grease and wash with hot water and detergent. Roughen all painted surfaces with medium 3M ScotchbriteTM pad. Rinse thoroughly with water.\nTreat any bare aluminum with chromate conversion coating. Clean the entire area with an acid cleaner that does not contain fluoride, such as DuPont 5717. Scrub the surface with 3M ScotchbriteTM pad until it is completely “wetted” with no beads of water.\nNote! Fluoride in a cleaner causes a “smut” (dark discoloration on silicon-alloy aluminum castings), and paint will not stick to “smut”. If this happens, sand the surface and start over using a different acid cleaner.\nNote! Do not use steel wool. Small pieces of steel wool become embedded in the aluminum and will cause severe corrosion.\nRinse thoroughly with water. The area must appear “wetted” or the surface is not clean, and paint will not adhere.\nWhile the surface is still wet from rinsing, treat all bare aluminum with DuPont 226S chromate conversion solution. Brush the chromate solution as required for 2 to 5 minutes to prevent it from drying on the surface. Rinse the surface thoroughly with water and allow to air dry. Follow the label instructions exactly.\n–If the chromate is allowed to dry anywhere on the bare aluminum surface, chromic acid salts will form which will prevent paint adhesion and promote corrosion. Sand the surface to bare metal. –It is best to let the part air dry, but if you must wipe the surface to speed up drying, use lint free wipes not treated with anything that may contaminate the surface. Do not scrub the surface, wipe very lightly. –Do not blow dry with shop air unless it is completely free of dirt, oil, and water. –Do not heat the part above 150°F, before painting. –Do not touch the treated surface with bare bands before painting. –The part should be primed soon after it dries, or at least within 24 hours.\nWhere the prime coat is thin or where the surface is unpainted, prime with Volvo Penta Primer or PPG Super Koropon epoxy primer. Do not apply primer over hard finish coat. Primer solvents must be allowed time to evaporate and the primer must harden before applying the finish coat. Allow 8 to 12 hours drying time.\nApply finish coat. The parts catalogs list numbers for finishing products.\nOk\u0026hellip; här visar det sig gömmas ett helt kunskapsområde att gräva i som de flesta inte har en aning om vad det är. Pröva med att fråga ditt varv om de vet vad kromatering eller passivering av aluminium är, eller om de hört talas om Alodine!\nMedlen som nämns, DuPont 5717 samt DuPont 226S är en metallpreparationsvätska resp. en kromateringsvätska. Dessa ämnen finns i olika tappningar från olika leverantörer, exempelvis motsvarande DX533 samt DX503 från PPG eller olika varianter kallade Alodine från Henkel. Preparationsvätskan kallas ofta för Alumiprep 33 (dock ej den vi ska använda till ett DP-S/SX-drev, läs vidare) och kromateringsvätskan kallas generellt för Alodine, det är visserligen ett produktnamn men har blivit näst intill synonymt med \u0026ldquo;kromateringsvätska för aluminium\u0026rdquo;.\nNOT: \u0026ldquo;State of the art\u0026rdquo; idag är tydligen elektrokeramisk behandling kallad Alodine EC2 Preparationsvätskan är i grunden baserad på forsforsyra som helt enkelt djuprengör ytan från oxidering, korrosion och annat jox. Kromateringsvätskan genomför en kromatering (även kallat mer generellt för passivering ) av aluminiumets yta, dvs det är ett extremt tunnt lager som kemiskt binds mycket starkt med det yttersta skiktet av aluminiumet. Detta skikt förhindrar korrosion och ger en mycket bättre yta att måla vidare på. Detta är otroligt viktigt för resten av målningsprocessen ifall vi vill ha en lackering som håller lika bra som Volvo Pentas originallack dsv mer än några få säsonger - kort sagt, kromateringen sitter benhårt på aluminium och primern sitter benhårt på kromateringen i sin tur! Volvo Penta har (läste jag någonstans) under 30 år använt denna kromatering i deras lackprocess.\nAlodine har traditionellt varit baserat på sexvärt krom , giftigt som satan! Kommer du ihåg Erin Brockovich ? Japp, sexvärt Krom. Kallas \u0026ldquo;hexavalent\u0026rdquo; på engelska. Jag utgår ifrån att Volvo använt Alodine baserat på sexvärt krom. Ifall man googlar på nyckelord som passivering av aluminium, kromatering osv så hittar man svenska industriföretag som sysslar med detta.\nJag hittade också denna mycket bra beskrivning av en person som använt ovanstående process själv för att måla drev, med goda resultat.\nMen hur ska vi göra som privatpersoner? För det första hittar jag inga affärer i Sverige som saluför dessa ämnen, rätta mig ifall jag har fel. För det andra vill i alla fall inte jag ta i sexvärt krom med en 5 meter lång tång ens, det är cancerogent och man måste ha avancerad skyddsutrustning osv. Inget för hobby-Pelle hemma på gården alltså! Men under senare år har det alltså dykt upp en rad olika alternativa vätskor/processer som exempelvis ChromitAL TCP, Surtec 609 Zetacoat osv. Flera av dessa baseras på trevärt krom som inte alls är giftigt!\nPå nätet finns det en affär som de flesta jänkare refererar till , och där finns alla dessa ämnen - men de levererar inte internationellt\u0026hellip; Efter att ha pratat med tonvis med folk så hade jag vid det här laget bestämt mig för att hoppa över kromateringen och köra på den varianten som de flesta rekommenderar:\nSlipa ner, undvik stål och sand. Jag försöker behålla originallackskiktet där det går. Har ingen bläster som såklart är det bästa utan använder skrapa + aluoxidpapper + borrmaskin med slipstift eller icke stålborste.\nAnvänd avfettning, typ Henkel Degreaser, finns i båtshoppen. Tar bort fetter och oljor osv.\nHögtryckstvätta som en idiot. Möjligen slabba på slutet med avjoniserat vatten för att bli av med salter i kranvattnet.\nMåla med en 2-komponents epoxy primer enligt instruktion. Jag valde att köpa Henkels standardprimer från båtshoppen. Första lagret ska målas förtunnat, sedan 3-4 lager till.\nDags för Volvos originalfärg på sprayburk. DP-S har metallic.\nMetallic behöver klarlack, Volvos återigen på sprayburk.\nVärt att notera med ovanstående är:\nVi använder inte självetsande primer. För det första är det enligt flera \u0026ldquo;old school\u0026rdquo;. För det andra tycks epoxy primern har svårt att fästa på sådan primer och de flesta avråder från det. För det tredje har International slutat att sälja sin Etching Primer och rekommenderar istället att göra som Henkels epoxy primer beskriver - förtunnat lager och därefter en rad lager till, direkt på aluminiumet. De anser att det blir bättre än etsande primer tydligen, enligt en kille på färgaffären.\nDegreasern klarar inte av att få bort oxidationen och jag är osäker på hur effektiv den är mot kiseln som ju finns inne i aluminiumet. Detta tillsammans med att vi inte fått stopp på aluminiumets korrosionsförmåga och att primern har svårt att fästa på aluminiumet är de stora svagheterna. Inte undra på att alla som sysslar med detta säger att, \u0026ldquo;Tja, du får vara beredd på att måla om efter några säsonger\u0026hellip;\u0026rdquo;. Färgen fäster helt enkelt inte tillräckligt bra och oxidationen kommer tillbaka.\nDet gnagde i mig att det borde gå att få tag på de där två vätskorna ändå. Det var då jag till slut hittade www.chemical-supermarket.com - aha! De har både giftiga varianter och moderna sorter fria från sexvärt krom. Game on!\nJag satsar på Chromital TCP från Henkel dvs T5900-TCP samt Metal Prep 79 som preparationsvätska istället för Alumiprep. Detta eftersom jag hittat på nätet att Metal Prep 79 rekommenderas av Henkel för kisel-aluminiumlegeringar eftersom den ej innehåller fluor, också noterat i Volvos instruktion. Alumiprep 33 avråder Henkel ifrån. T5900-TCP (TCP står för Trivalent Chromium Process) har också erhållit militärt godkännande i USA och visar näst intill lika bra egenskaper som referensprodukten Alodine 1200S (sexvärt krom) samt är inte alls lika giftig och läskig att använda. De helt kromfria varianterna visar inte riktigt lika bra resultat som TCP-varianterna.\nNär jag ändå bestämt mig för att köpa saker från chemical-supermarket så slog jag också till på deras Epoxy Primer som verkar vara riktigt vass, också godkänd för militärt bruk, samt deras stripper EFS 2500 för färgborttagning, uppenbarligen något i hästväg. Ska bli intressant att se ifall strippern kan ta resten av färgen på drevet utan slipning!\nAlla fyra produkter landar totalt på 174 dollar, men FedEx-frakten går lös på 253 dollar! Vi landar således på 427 dollar dvs cirka 2700:-, inte billigt direkt.\nNu ser vår reviderade process ut såhär:\nPröva EFS-2500 Paint Stripper. Ifall den funkar extremt bra så gör jag drevet 100% rent. Annars försöker jag behålla originallacken där det går. Har ingen bläster som såklart är det bästa utan använder skrapa + sandpapper + borrmaskin med slipstift eller icke stålborste.\nAnvänd avfettning, typ Henkel Degreaser, finns i båtshoppen. Tar bort fetter och oljor osv.\nHögtryckstvätta.\nAnvänd Metal Prep 79 enligt instruktion. Penslas på några minuter och sköljs av, skall ej torka på ytan. Vattnet skall sluta bilda droppar. Gummihandskar, förkläde och skyddsglasögon samt god ventilation är viktigt!\nHögtryckstvätta samt skölja med avjoniserat vatten för att bli av med salter i kranvattnet.\nAnvänd T5900-TCP enligt instruktion. Penslas på några minuter och sköljs av. Gummihandskar, förkläde och skyddsglasögon samt god ventilation är viktigt!\nMåla med Stratocoat Green epoxy primer enligt instruktion. Antagligen 2-3 lager.\nDags för Volvos originalfärg på sprayburk. DP-S har metallic så det blir klarlack på det också.\nKlarlack, Volvos återigen.\nVi är därmed uppe i cirka 6 lager, vilket ju är barnsligt jämfört med Volvos 19 i deras process! :) Steg 8 och 9 skulle kunna vara mer avancerade men jag kör gärna Volvo originalprylar på den nivån.\nDetta är sålunda planen, i nästa artikel tänker jag visa steg för steg med bilder och detaljerade instruktioner samt tidsåtgång.\nIfall jag har faktafel, kommentera så justerar jag gärna. Ifall någon har mer kunskaper i ämnet, kommentera så lägger jag gärna till. Ifall någon firma erbjuder tjänster för kromatering av drev - maila så kan jag lägga in länkar till er.\n"},{"title":"Tirade, supporting embedded text","permalink":"https://goran.krampe.se/2011/04/15/tirade-supporting-embedded-text/","summary":"\u003cp\u003eTwo years ago I ended up creating \u003ca href=\"http://goran.krampe.se/2009/03/16/tirade-a-file-format-for-smalltalkers/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eTirade\u003c/a\u003e\n - a new \u0026ldquo;file format\u0026rdquo; for Smalltalkers. Or rather, a way to serialize stuff into a sequence of Smalltalk messages with literals as arguments. I have written a \u003ca href=\"http://goran.krampe.se/categories/tirade\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003efew blog articles about Tirade\u003c/a\u003e\n so I will not go into details in this one.\u003c/p\u003e\n\u003cp\u003eOne thing that has been disturbing with Tirade is that I wanted it to be the main format for serializing Deltas, the new implementation of \u0026ldquo;21st Century ChangeSets\u0026rdquo;. This means I want Tirade to handle Smalltalk source code in the best possible way. Ideally I would want the Tirade file to be editable in a text editor if I wanted, and not being broken by that.\u003c/p\u003e","content":"Two years ago I ended up creating Tirade - a new \u0026ldquo;file format\u0026rdquo; for Smalltalkers. Or rather, a way to serialize stuff into a sequence of Smalltalk messages with literals as arguments. I have written a few blog articles about Tirade so I will not go into details in this one.\nOne thing that has been disturbing with Tirade is that I wanted it to be the main format for serializing Deltas, the new implementation of \u0026ldquo;21st Century ChangeSets\u0026rdquo;. This means I want Tirade to handle Smalltalk source code in the best possible way. Ideally I would want the Tirade file to be editable in a text editor if I wanted, and not being broken by that.\nSo, what properties do we want:\nNo escaping of special characters. In regular Tirade strings (just like in Smalltalk) need to escape the single quote as doubled single quote, and that would suck for Smalltalk code of course.\nNo length encoding. One way to avoid escaping is to store the length of the data before the actual data - like a Netstring for example. This prohibits easy editing in a text editor though, since that would change the length.\nA reasonable syntax. Tirade so far has been a subset of Smalltalk (disregarding lack of receiver to the left), but I think we might have to break that a bit here.\nAfter pondering this for a while I have come up with this solution which feels kinda nice, but if someone has an even better idea I am all ears. This is how it could look embedding a method source in Tirade: class: #MyClass selector: #at:put: source: [ at: pos put: arg \u0026ldquo;Put something here\u0026rdquo;\n^array at: pos put: arg ]. So what gives here? We are reusing the syntax for Smalltalk blocks without arguments. Simply [\u0026hellip;content\u0026hellip;]. The content will be delivered as a String and the guarantee is that it will be received exactly as sent. There is a trick here - this is what Tirade will do:\nWrite the starter $[ and then a CR\nBefore each line in the string (a line being all characters up to and including the next CR or up to end) we insert a TAB. This means that the String begins on the line after the opening $[ and all lines will be prefixed with a TAB.\nThen, regardless if the last line ended with a CR or not - we add a CR before the closing $]. This makes sure the closing $] ends up on its own line.\nThe above trick gives us the ability to detect the end of the string because if a line starts with something else than a TAB then we have reached the end. Thus we do not have to escape the $] inside the string and we still don\u0026rsquo;t need to do length encoding. We DO however need to make sure all lines begin with a TAB, but if you are editing a Tirade file you should just learn that fact. :)\nI am not sure if the above is a good solution, but it is ONE solution and I can\u0026rsquo;t come up with a better one, unless we would use a really \u0026ldquo;odd\u0026rdquo; marker at the end in order to not have to escape it, but that feels \u0026ldquo;dirty\u0026rdquo; to me.\n"},{"title":"Preaching Smalltalk inside a nuclear reactor","permalink":"https://goran.krampe.se/2011/04/08/preaching-smalltalk-inside-a-nuclear-reactor/","summary":"\u003cp\u003e\u0026hellip;is what I did yesterday. It was the \u003ca href=\"http://sites.google.com/site/stockholmgtug\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eStockholm GTUG\u003c/a\u003e\n group having a loose and laid back meetup in a rather special venue - R1, \u003ca href=\"http://sv.wikipedia.org/wiki/R1_%28reaktor%29\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSweden\u0026rsquo;s first nuclear reactor\u003c/a\u003e\n! 27 meters below ground, kinda\u0026hellip; funky.\u003c/p\u003e\n\u003cp\u003eAnyway, I tried doing an ultra compact version of several of my other presentations around \u003ca href=\"http://www.world.st\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSmalltalk\u003c/a\u003e\n and \u003ca href=\"http://www.seaside.st\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSeaside\u003c/a\u003e\n - didn\u0026rsquo;t really go 100% since I both had some technical issues (keyboard problems and projector issues too) and ended up taking more time than was planned. Hopefully noone got upset about that.\u003c/p\u003e","content":"\u0026hellip;is what I did yesterday. It was the Stockholm GTUG group having a loose and laid back meetup in a rather special venue - R1, Sweden\u0026rsquo;s first nuclear reactor ! 27 meters below ground, kinda\u0026hellip; funky.\nAnyway, I tried doing an ultra compact version of several of my other presentations around Smalltalk and Seaside - didn\u0026rsquo;t really go 100% since I both had some technical issues (keyboard problems and projector issues too) and ended up taking more time than was planned. Hopefully noone got upset about that.\nIn about 60 minutes I taught the whole language in 5 slides (the language is very small from a semantic and grammatic view), a bit of the amazing history behind Smalltalk, some of the traditional tools in a classic Smalltalk environment - and finally, a quick whipup of a Todolist app in Seaside, including support for the back button! I used Squeak and Pharo and I hope I get to do a similar presentation some other time - then I will polish it and try to keep the \u0026ldquo;blitz\u0026rdquo; tempo. Shock and awe. :)\nI think the audience appreciated it (always hard to tell), would have been nice to show more of course - I could easily spend a whole day teaching Smalltalk and various mind blowing aspects around the environment, the language, cool libraries and techniques - and of course Seaside.\nThen I spent some time chatting with my friend Mikael Kindborg (also a Smalltalker at heart) and a couple of his colleagues from Mosync who were actually sponsoring the event with beer, wine and sandwiches. It was a nice evening and it\u0026rsquo;s always fun to show Smalltalk to people who have never seen it.\n"},{"title":"Node.js vs Nginx/Squeak, part 1","permalink":"https://goran.krampe.se/2011/03/14/node-js-vs-nginxsqueak-part-1/","summary":"\u003cp\u003eHmmm, after seeing the \u003ca href=\"http://nodejs.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNode.js\u003c/a\u003e\n presentation at \u003ca href=\"http://swdc-central.com/dyncon2011/index.html\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eDyncon 2011\u003c/a\u003e\n I couldn\u0026rsquo;t help installing Nginx and Blackfoot (SimpleCGI) in a Squeak 4.2 image running on the Cog VM to make some performance tests! In fact I started doing that during the presentation. :)\u003c/p\u003e\n\u003cp\u003eMy first run on Nginx/Squeak looked quite unimpressive. Well, one client doing 1300 req/s to a small helloworld was decent although Node.js handled approximately 2x that. With Nginx we have a two tier solution so a factor of 2 is not really surprising in this trivial case. Top showed similar load, both solutions only seem to consume 8-9% of my CPU power on this box, but the Nginx/Squeak solution of course spreads load between them with approximately 1/3 or 1/4 on nginx.\u003c/p\u003e","content":"Hmmm, after seeing the Node.js presentation at Dyncon 2011 I couldn\u0026rsquo;t help installing Nginx and Blackfoot (SimpleCGI) in a Squeak 4.2 image running on the Cog VM to make some performance tests! In fact I started doing that during the presentation. :)\nMy first run on Nginx/Squeak looked quite unimpressive. Well, one client doing 1300 req/s to a small helloworld was decent although Node.js handled approximately 2x that. With Nginx we have a two tier solution so a factor of 2 is not really surprising in this trivial case. Top showed similar load, both solutions only seem to consume 8-9% of my CPU power on this box, but the Nginx/Squeak solution of course spreads load between them with approximately 1/3 or 1/4 on nginx.\nBut jacking up concurrent clients really destroys Nginx/Squeak! How come? I was surprised because my memory of this when I wrote Blackfoot was that it was handling that fairly ok. Trying 50 concurrent clients with Node.js pushes it up to almost 8000 req/s! Quite impressive and it still only uses about 9% of my CPU power. Blackfoot ends up serving less than 1/10nth of that. Now, thinking and looking more closely it is quite obvious - SCGI opens a new connection for each request\u0026hellip; ouch. Why on earth did they design SCGI like that? So basically Nginx will hammer Squeak just like we hammer Nginx I guess, and Squeak doesn\u0026rsquo;t deal with that too nicely.\nA small experiment with firing up 3-5 Squeak backends and letting Nginx load balance over them (really simple to do) shows that we can get around this somewhat and scare Blackfoot into serving over 3000 req/s and still not going over 30% CPU. Not that shabby, but still not in the same league as Node.js, but now we know why - we need a solution that holds the connection open between Nginx and the backend.\nAt this point I wanted to try three things:\nWhat numbers can Nginx on its own produce, just returning a small HelloWorld file?\nWhat numbers can plain KomHttpServer running on Cog produce?\nAnd finally, how does Nginx/AJP/Squeak behave? AJP does keep the connection open I think.\nLet\u0026rsquo;s guess first - plain Nginx should beat Node.js, Kom with Cog is probably not much faster than regular Squeak VM since the issues I believe are in the Socket plugin (and we saw that it didn\u0026rsquo;t like getting hammered by Nginx), and finally I am hoping AJP puts Squeak at say half Node.js even with 50 concurrent clients, that would be 4000 req/s and I would be darn happy. And of course, with a load balancer on top even more, but that can be done with Node.js also of course. So more on that next time\u0026hellip;\n"},{"title":"Dyncon 2011, retrospect","permalink":"https://goran.krampe.se/2011/03/14/dyncon-2011-retrospect/","summary":"\u003cp\u003eSo it\u0026rsquo;s monday and I am getting started with work but thought I should try writing a retrospective of \u003ca href=\"http://swdc-central.com/dyncon2011/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eDyncon 2011\u003c/a\u003e\n during the day. In summary it was a nice and largish crowd (about 85), a spacious and good venue in the middle of the city (office of BWin/Ongame) with a great view from the 11th floor and a good \u003ca href=\"http://swdc-central.com/dyncon2011/speakers.html\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003elineup of speakers\u003c/a\u003e\n. Perhaps I am getting old though but having this many speakers doing 40 min presentations for two full days\u0026hellip; well, I kinda like to have time to sit down and chat with people and show stuff and so on. Not much time for that, and 40 minutes means that most presentations got stressed for time even though flying on a rather high level. But still, \u003cstrong\u003ea fun and interesting conference\u003c/strong\u003e!\u003c/p\u003e","content":"So it\u0026rsquo;s monday and I am getting started with work but thought I should try writing a retrospective of Dyncon 2011 during the day. In summary it was a nice and largish crowd (about 85), a spacious and good venue in the middle of the city (office of BWin/Ongame) with a great view from the 11th floor and a good lineup of speakers . Perhaps I am getting old though but having this many speakers doing 40 min presentations for two full days\u0026hellip; well, I kinda like to have time to sit down and chat with people and show stuff and so on. Not much time for that, and 40 minutes means that most presentations got stressed for time even though flying on a rather high level. But still, a fun and interesting conference!\nFor me the most interesting part was talking with Joe Armstrong , it turned out he wanted a bridge between Erlang and Squeak and was looking for someone to write a Socket server for him in Squeak. Funny enough I know quite a lot about that, but more on that in another post. I was also somewhat pleasantly surprised about his knowledge of the Smalltalk community and his view of Smalltalk. I forgot to point him to my \u0026ldquo;bashing\u0026rdquo; of his OO article a few years back :)\nAt the end of the day I would say it was a success but if I were to organize a follow up conference I would try to have a few longer presentations, mixed with a some very short ones. And also put in some other kind of \u0026ldquo;format\u0026rdquo; - like a panel debate and also more time to just \u0026ldquo;hang\u0026rdquo; together and self organize a bit. Well, just my 2 cents.\n"},{"title":"Dyncon 2011, day 2","permalink":"https://goran.krampe.se/2011/03/13/dyncon-2011-day-2/","summary":"\u003cp\u003eDay one must have ended with lots of beer because people were quite late for day two. 15 minutes late Carl Lerche finally started his Ruby presentation. One thing I found interesting was Ruby Modules vs Monticello extension methods (in some ways I presume this is how Modules are often used - to extend other classes with behavior). Evidently \u0026ldquo;method extensions\u0026rdquo; to the class side in Ruby doesn\u0026rsquo;t work like extensions to the instance side, it does in Smalltalk of course :). Then Carl described ways to still do this, but it looked complex, and also explaining there are lots of \u0026ldquo;hooks\u0026rdquo; when messing with the MOP. Is that a good thing? If Rubyists use this a lot, then I presume utter hopeless confusion might occur.\u003c/p\u003e","content":"Day one must have ended with lots of beer because people were quite late for day two. 15 minutes late Carl Lerche finally started his Ruby presentation. One thing I found interesting was Ruby Modules vs Monticello extension methods (in some ways I presume this is how Modules are often used - to extend other classes with behavior). Evidently \u0026ldquo;method extensions\u0026rdquo; to the class side in Ruby doesn\u0026rsquo;t work like extensions to the instance side, it does in Smalltalk of course :). Then Carl described ways to still do this, but it looked complex, and also explaining there are lots of \u0026ldquo;hooks\u0026rdquo; when messing with the MOP. Is that a good thing? If Rubyists use this a lot, then I presume utter hopeless confusion might occur.\nObviously there is a difference here I think between the Smalltalk and Ruby mindset - in Smalltalk we are always in runtime, but that doesn\u0026rsquo;t mean we go crazy on the dynamic axis - that would pull the rug out from the development environment and its capabilities in navigating and describing the code base, in much the same way as a macro system does in C/C++. Next part was about various techniques using Ruby blocks, like for example messages taking optional blocks\u0026hellip; hmmm, trying to figure out what I think of that. \u0026ldquo;File.open\u0026rdquo; was showed as an example. Reading on the net shows that there is a lot of\u0026hellip; complexity regarding blocks in Ruby, doesn\u0026rsquo;t look nice. I hate needless complexity. Evidently Ruby 1.9 is cleaning up blocks - curious if anyone could elaborate on that compared to Smalltalk.\nNext up was Tom Hughes-Croucher from Joyent presenting Node.js . In essence this is about hard scaling of network applications. He began by talking about scaling issues with regular forking architectures and V8 and the AreWeFastYet website etc. Javascript is indeed getting an awful lot of performance attention these days and that of course makes it the \u0026ldquo;assembler of the Internet\u0026rdquo; and a compelling base platform for more and more things. Although I do understand this I still don\u0026rsquo;t really see how Node.js would be extremely better than say Nginx + a backend that doesn\u0026rsquo;t allocate insanely much memory per user session? For example, using Nginx (or Cherokee) with a Squeak backend running AJP, it would be fun to compare performance wise.\nSergi Mansilla then presented Cloud9 , a web based IDE for Javascript. Mmmmm, well, I don\u0026rsquo;t get excited about that because I am a Smalltalker and the things I can do with Squeak /Pharo \u0026hellip; sorry, I don\u0026rsquo;t want it in the browser! What about interactive graphics visualization? Really good browsers? Sure, it can be done, and compared to vim/emacs it might be cool. But I want to be able to hack my IDE for example. It is clearly a really ambitious project though and worth keeping track of since they are pushing the boundaries of what you can do on the web.\nRobert Virding doing another presentation around Erlang, similar to the one Joe did yesterday but still different. Focusing more on principles but also with some code examples. Somewhat interesting, but I didn\u0026rsquo;t follow it too closely.\nAfter lunch Björn Eiderbäck started his presentation on Smalltalk directly in the latest version of VisualWorks from Cincom. The style of Björn\u0026rsquo;s presentation is to interactively using the Smalltalk environment trying to quickly \u0026ldquo;dig into\u0026rdquo; code and using its tools. This style easily gets side tracked but in order to make non Smalltalkers understand the \u0026ldquo;beauty\u0026rdquo; of Smalltalk it might be the way to do it in a short period of time, Shock and Awe. :)\nThe day continues but I am posting this now anyway.\n"},{"title":"Dyncon 2011, day 1","permalink":"https://goran.krampe.se/2011/03/12/dyncon-2011-day-1/","summary":"\u003cp\u003eIn place at \u003ca href=\"/http://swdc-central.com/dyncon2011/\" \u003eDyncon 2011 \u003c/a\u003e\nat Bwin/Ongame in Stockholm. Quite a nice crowd and the day was started with Joe Armstrong presenting \u003ca href=\"http://www.erlang.org\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eErlang\u003c/a\u003e\n. I had never seen Joe speak before and it was a fun and interesting presentation, although of course only \u0026ldquo;skimming\u0026rdquo; some areas. I found it fun that he referenced Alan Kay where he stressed that \u0026ldquo;it\u0026rsquo;s the messages\u0026rdquo;, given his earlier harsh view on OO. I couldn\u0026rsquo;t help starting to think about how some of Erlang\u0026rsquo;s concepts could easily be implemented in Smalltalk and what that could give.\u003c/p\u003e","content":"In place at Dyncon 2011 at Bwin/Ongame in Stockholm. Quite a nice crowd and the day was started with Joe Armstrong presenting Erlang . I had never seen Joe speak before and it was a fun and interesting presentation, although of course only \u0026ldquo;skimming\u0026rdquo; some areas. I found it fun that he referenced Alan Kay where he stressed that \u0026ldquo;it\u0026rsquo;s the messages\u0026rdquo;, given his earlier harsh view on OO. I couldn\u0026rsquo;t help starting to think about how some of Erlang\u0026rsquo;s concepts could easily be implemented in Smalltalk and what that could give.\nNext up was Yehuda Katz presenting Sproutcore . An \u0026ldquo;all\u0026rdquo; javascript framework to build \u0026ldquo;rich\u0026rdquo; client apps in the browser. Hmmm\u0026hellip; there are so many of these now. Claims a proper MVC architecture. But I really don\u0026rsquo;t want to build my apps in Javascript :). Generating Javascript - yes, writing it - no thanks. And I am really not impressed with frameworks/toolsets that are template oriented with various quirky ways of \u0026ldquo;binding\u0026rdquo; stuff together. I have become too spoiled by the HTML DSL approach in Seaside to think template engines are \u0026ldquo;cool\u0026rdquo;. Ouch, my eyes hurt!\n"},{"title":"No more coppar!","permalink":"https://goran.krampe.se/2010/11/26/no-more-coppar/","summary":"\u003cp\u003eOur ADSL broke a week ago and the \u003ca href=\"http://www.kustbandet.com\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eoperator\u003c/a\u003e\n decided to NOT repair it, since they can\u0026rsquo;t see the economy in doing so.\u003c/p\u003e\n\u003cp\u003eAfter pondering the options I decided to try 3G all the way. Since I already have a Telia USB modem (Option icon 505) I just needed a good wifi router that can use it.\u003c/p\u003e\n\u003cp\u003eEnded up buying a \u003ca href=\"http://www.dovado.com/4GR.html\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eDovado 4GR\u003c/a\u003e\n, really simple to set up and to upgrade firmware in. It is important to try different locations in the house though, got 3x more speed near the window on the second floor.\u003c/p\u003e","content":"Our ADSL broke a week ago and the operator decided to NOT repair it, since they can\u0026rsquo;t see the economy in doing so.\nAfter pondering the options I decided to try 3G all the way. Since I already have a Telia USB modem (Option icon 505) I just needed a good wifi router that can use it.\nEnded up buying a Dovado 4GR , really simple to set up and to upgrade firmware in. It is important to try different locations in the house though, got 3x more speed near the window on the second floor.\nNext move is to get ip-telephony working on top.\n"},{"title":"Skype interview with Dan Ingalls","permalink":"https://goran.krampe.se/2010/09/10/skype-interview-with-dan-ingalls/","summary":"\u003cp\u003eBefore the summer I had the opportunity to do a Skype interview with Dan \u003ca href=\"http://en.wikipedia.org/wiki/Daniel_Henry_Holmes_Ingalls,_Jr.\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eIngalls\u003c/a\u003e\n, the \u0026ldquo;Guido/Larry/Linus\u0026rdquo; of Smalltalk.\u003c/p\u003e\n\u003cp\u003eThe interview was part of a guest lecture I did at \u003ca href=\"http://dsv.su.se/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eDSV\u003c/a\u003e\n for the \u003ca href=\"http://people.dsv.su.se/~beatrice/DYPL\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eDYPL\u003c/a\u003e\n course (dynamic programming languages) held by Beatrice Akerblom. In the end I only used a smaller quote because most of the topics in the interview ended up being more interesting to \u0026ldquo;true believers\u0026rdquo; than to Smalltalk newcomers.\u003c/p\u003e","content":"Before the summer I had the opportunity to do a Skype interview with Dan Ingalls , the \u0026ldquo;Guido/Larry/Linus\u0026rdquo; of Smalltalk.\nThe interview was part of a guest lecture I did at DSV for the DYPL course (dynamic programming languages) held by Beatrice Akerblom. In the end I only used a smaller quote because most of the topics in the interview ended up being more interesting to \u0026ldquo;true believers\u0026rdquo; than to Smalltalk newcomers.\nI admit to not having planned the interview in perfect detail so rather quickly it degenerated into an informal discussion, with my daughter interrupting at random places. :) So I did some \u0026ldquo;post production work\u0026rdquo; and edited it into approximately 22 minutes of Q\u0026amp;A. For technical woes, see my earlier post .\nSince the ESUG 2010 soon is here (can’t attend unfortunately) this is my small contribution, enjoy (10Mb).\nregards, Goran\n"},{"title":"Making a Skype interview...","permalink":"https://goran.krampe.se/2010/05/07/making-a-skype-interview/","summary":"\u003cp\u003eI got the opportunity to make a Skype interview with \u003ca href=\"http://en.wikipedia.org/wiki/Daniel_Henry_Holmes_Ingalls,_Jr.\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eDan Ingalls\u003c/a\u003e\n, so I decided to try to record it. Had no idea it was not as easy as a \u0026ldquo;press record\u0026rdquo;-button. I am on Ubuntu, Karmic Koala. First of all I had serious trouble getting proper sound working with Skype, I ended up following the HOWTO in order to install Skype 2.1 beta - which uses PulseAudio ONLY. That took care of that issue, after a bit of fiddling in the \u0026ldquo;Preferences\u0026rdquo; dialog you get when right-clicking on your volume applet :)\u003c/p\u003e","content":"I got the opportunity to make a Skype interview with Dan Ingalls , so I decided to try to record it. Had no idea it was not as easy as a \u0026ldquo;press record\u0026rdquo;-button. I am on Ubuntu, Karmic Koala. First of all I had serious trouble getting proper sound working with Skype, I ended up following the HOWTO in order to install Skype 2.1 beta - which uses PulseAudio ONLY. That took care of that issue, after a bit of fiddling in the \u0026ldquo;Preferences\u0026rdquo; dialog you get when right-clicking on your volume applet :)\nSo… I did roughly this:\nRecord both sides of the conversation using parec. This is a tool in PulseAudio, so the recording is done \u0026ldquo;outside\u0026rdquo; of Skype. In two different files! I used this shell script to record both sides at the same time (note that this produces RAW files): parec -r -d alsa_output.pci-0000_00_1b.0.analog-stereo.monitor \\ -n \u0026quot;Mon Rec\u0026quot; \u0026gt; mon-rec \u0026amp; \\ parec -r -d alsa_input.pci-0000_00_1b.0.analog-stereo \\ -n \u0026quot;Mic Rec\u0026quot; \u0026gt; mic-rec \u0026amp; Note that I found the alsa-yaddayadda names in… eh, some dialog somewhere! Don’t recall. Anyway, read more on this part here .\nI then converted the resulting two RAW audio files into WAV using sox, some kind of audio swiss army knife. I don’t have the exact one-liner handy, but I used the options found in the link above.\nFinally I mixed the two files together… eh, ah, problems… They don’t synch! Now… I have absolutely no idea how that can be, but the files end up drifting out of synch, and this seems to be a known Skype thing according to Mighty Google.\nSo in the end I had to manually cut/edit the two files in order to get a proper question+ answer sequence as an interview. I played with Audacity, ReZound etc but ended up doing it in Sweep, it felt simpler and didn’t cause me any other trouble.\nNOTE: On \u0026ldquo;other less worthy platforms\u0026rdquo; than Linux there seems to be other options. I also found some stuff for recording on Ubuntu, but AFAICT these solutions would not work with Skype 2.1.\nWell, perhaps it helps someone else out there intending to do the same journey!\n"},{"title":"Joe is wrong","permalink":"https://goran.krampe.se/2009/06/26/joe-is-wrong/","summary":"\u003cp\u003eI just read Joe Armstrong’s old \u0026ldquo;Why OO sucks\u0026rdquo; \u003ca href=\"http://www.sics.se/~joe/bluetail/vol1/v1_oo.html\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003earticle\u003c/a\u003e\n, Joe Armstrong being the inventor of \u003ca href=\"http://erlang.org/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eErlang\u003c/a\u003e\n. Granted, the article is from year 2000 I think, so perhaps I should cut him some slack… nah! :)\u003c/p\u003e\n\u003cp\u003eFirst of all - no, I haven’t programmed in Erlang (yet), but quite a lot of other programming languages. My favorite language is the grand father OO language - \u003ca href=\"http://squeak.org/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eSmalltalk\u003c/a\u003e\n. So sure, I am biased in favor of OO.\u003c/p\u003e","content":"I just read Joe Armstrong’s old \u0026ldquo;Why OO sucks\u0026rdquo; article , Joe Armstrong being the inventor of Erlang . Granted, the article is from year 2000 I think, so perhaps I should cut him some slack… nah! :)\nFirst of all - no, I haven’t programmed in Erlang (yet), but quite a lot of other programming languages. My favorite language is the grand father OO language - Smalltalk . So sure, I am biased in favor of OO.\nI have read other criticisms of OO, and various discussions about good or bad characteristics of OO in general and in specific OO languages… Sorry, this article is IMHO not among the good ones, and my feeling is that Joe wrote it quite quickly and with no real experience in programming in OO.\nBut I don’t intend to say his article \u0026ldquo;sucks\u0026rdquo; without arguing for why I feel it sucks :). And also, I am in great awe of the stuff Erlang makes possible so I have great respect for Joe - but that doesn’t mean he can’t be dead wrong.\nLet’s go through his article bit by bit:\n\u0026ldquo;Objection 1 - Data structure and functions should not be bound together\u0026rdquo; Link to heading I quote:\n\u0026ldquo;Since functions and data structures are completely different types of animal it is fundamentally incorrect to lock them up in the same cage.\u0026rdquo;\nRereading that first objection I only see kinder garten explanations of what functions and data are. I don’t see any real serious explanation of why they couldn’t be combined into objects other than \u0026ldquo;because they are different\u0026rdquo;. That is not an argument.\nIt is in fact quite logical to group functions and data together into objects based on their interaction patterns, if for no other reason.\nLet’s say we have data structures A, B, C and D. And we have functions q, x, y, z. If you start looking at what data is read and written by these functions you may find that q and x operates only on A and B, reading one and writing the other etc. So the functions and data structures form \u0026ldquo;natural clusters\u0026rdquo;, and usually these clusters are quite intuitively modelled as objects.\nPutting them together creates a boundary around this group of data and functions - encapsulation. Sure, you may call that a \u0026ldquo;module\u0026rdquo; but an object is IMHO slightly different since objects have identity, a life cycle and we can hold them, send them around etc.\nSo in some sense objects can probably be viewed as modules but often more fine granular. And we can combine such \u0026ldquo;modules\u0026rdquo; into larger modules (since objects have identity and can be referenced etc) and we can create and kill them dynamically (life cycle).\nIf I were coming from a language with a well developed \u0026ldquo;module\u0026rdquo; concept I can definitely see this as just \u0026ldquo;another step\u0026rdquo; forward.\nAnother interesting fact with objects having a life cycle is that since an object contains data A, B, C and D we now easily can create a whole such data \u0026ldquo;group\u0026rdquo; by just instantiating this object. And we deallocate them together as a single entity too - manually or automatically. Again, quite natural.\nSo ok, I can go on and on about this but since Joe didn’t really give any arguments I will stop there.\n\u0026ldquo;Objection 2 - Everything has to be an object.\u0026rdquo; Link to heading Now, being a Smalltalker I wouldn’t use the phrase has to be but I can clearly see all the benefits when the paradigm is really followed through in a pure way.\nOk, but let’s look at what Joe says. He points to an example - different datatypes for describing amount of time, or well, not \u0026ldquo;amount\u0026rdquo; but in fact partial pieces of points in time. Hour (of day), minute (of hour), year etc. Without knowing Erlang these data type definitions typically define ranges of integer values valid for these types. Anyway, then his main points are:\nThese data types can be used everywhere.\nThere are no associated methods.\nThe first argument is odd. Let’s look at Smalltalk (or any OO language), let’s say we have a class called TimeStamp. Or Date. We can instantiate these classes from anywhere in the system, there is no reason for classes to have any less (or more) scope than data types. So objects of classes can also be used \u0026ldquo;everywhere\u0026rdquo;.\nThe second argument is plain dumb (sorry). No associated methods? There are TONS of interesting behavior you can attach to these kinds of objects! For a true tour de force, just look at Chronos for example. The fact that Joe can make such a claim is IMHO clearly showing that he really haven’t seen how a good OO library can work. Or I suspect ever programmed in an OO language in fact.\nBut if we disregard this bad example, going back to the original objection, I agree - everything does not HAVE to be an object. But a LOT of the problems in many OO languages can be traced to the fact that they still retain lots of \u0026ldquo;fundamental data types\u0026rdquo; that are not objects. And most of the modern OO languages get closer and closer to Smalltalk where almost everything really is an object, just look at Python, Ruby, Scala etc.\nThe object concept is very powerful and its power gets even greater when applied generously. :)\n\u0026ldquo;Objection 3 - In an OOPL data type definitions are spread out all over the place.\u0026rdquo; Link to heading Ehm, sorry Joe but this one really shows poor understanding of OO languages. First of all, I presume you mean \u0026ldquo;data type definition\u0026rdquo; as an enum or similar. Or a class definition. Ok, and then you seem to say it is a pity that you can’t just put them in one single place - ehrm, but you can… but it would be rather horrendous design.\nIt is simple normal modularisation, you don’t want ALL data types/classes defined in a big global scope, right? I would in fact argue in the exact OPPOSITE - in an OOPL data type definitions are where they should be - close to the place of use. The modular way.\nAnyway, now we come to the last paragraph - and it is simply confused. Let me quote:\n\u0026ldquo;In an OOPL I have to choose some base object in which I will define the ubiquitous data structure, all other objects that want to use this data structure must inherit this object. Suppose now I want to create some \u0026ldquo;time\u0026rdquo; object, where does this belong and in which object\u0026hellip;\u0026rdquo;\nNo, no, no - why would all other objects need to inherit that class? Inheritance is normally used for specialization, the mechanism you are totally missing is composition. If my Account object needs to have a TimeStamp in it - then I simply instantiate a TimeStamp and let my Account hold onto it in an instance variable. This is basic OO, chapter 1.\nIt is also amusing that the examples of \u0026ldquo;ubiquitous data types\u0026rdquo; mentioned are LinkedList, Array and Hashtable. All three being standard collection classes that almost all OO languages have, no problem there, sorry. Note that Erlang was created around 1990. Smalltalk was created in the late seventies and Simula in 1967. Smalltalk has worked very successfully with an \u0026ldquo;all objects\u0026rdquo; approach and having very rich and appreciated collection classes - including LinkedList, Array and Dictionary (Hashtable). It feels like Joe thinks OO came around in 1996 with Java - nope, it is in fact much older than Erlang.\n\u0026ldquo;Objection 4 - Objects have private state.\u0026rdquo; Link to heading Again, confused arguments. Quote:\n\u0026ldquo;OOPLs say \u0026lsquo;hide the state from the programmer\u0026rsquo; \u0026quot;\nWell, yeah, in an encapsulation-and-modularity-is-good-kinda-way. Not in a programmers-should-not-care-or-know-kinda-way.\nThe argument about C/Pascal using scoping rules - ehm, well, OOPLs do too, hard to see the distinction there. Joe call’s the OO idea of encapsulation as the \u0026ldquo;worst possible choice\u0026rdquo;. But again, no real argument for why encapsulation would be a bad thing. In fact it is one of the most important aspects of OO - the ability to expose a concept - an object - in a comprehensive high level way with a nicely designed API without forcing the user to look at all the details inside. Classical black box composition, an idea older than… old :)\nAnd no, the blackness does not have to be strict - if the programmer wants to look I say go right ahead. I am definitely not defending the pretentious protective ideas gone berzerk in languages like Java, C++ and C# where keywords like \u0026ldquo;final\u0026rdquo;, \u0026ldquo;sealed\u0026rdquo;, \u0026ldquo;private\u0026rdquo;, \u0026ldquo;protected\u0026rdquo; etc tend to simply make life miserable for the programmer who actually knows exactly what he or she is doing. But enough of that little rant, claiming that encapsulation is a BAD THING is … simply daft.\nThe final conclusion about why OO got popular does not hold any substance either - I am not even going into it. So all in all I think Joe is totally off in this article. :) Having said that I still look forward to learn Erlang, and since I am dabbling with CouchDB I might get my feet wet soon.\nNOTE in 2011: Now I have finally met Joe and almost feel embarrassed of the above \u0026ldquo;bashing\u0026rdquo;. But only almost :)\n"},{"title":"Tirade, first trivial use","permalink":"https://goran.krampe.se/2009/04/20/tirade-first-trivial-use/","summary":"\u003cp\u003eLast night I started hooking \u003ca href=\"http://goran.krampe.se/2009/03/16/tirade-a-file-format-for-smalltalkers/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eTirade\u003c/a\u003e\n into Deltas. Quick background: Deltas is \u0026ldquo;Changesets for the 21st century\u0026rdquo;, or in other words an intelligent patch system under development for Squeak. Tirade is a Smalltalk/Squeak centric \u0026ldquo;JSON\u0026rdquo;-kinda-thingy. I made Tirade in order to get a nice file format for Deltas. Just wanted to share how the first trivial code looks, and thus illustrate simple use of Tirade.\u003c/p\u003e\n\u003cp\u003eI have a DSDelta (a Delta being almost like a ChangeSet). It consists of some metadata (a UUID, a Dictionary of properties and a TimeStamp) and a DSChangeSequence (which holds the actual DSChange instances). As a first shot I only implemented the metadata bit. So step by step:\u003c/p\u003e","content":"Last night I started hooking Tirade into Deltas. Quick background: Deltas is \u0026ldquo;Changesets for the 21st century\u0026rdquo;, or in other words an intelligent patch system under development for Squeak. Tirade is a Smalltalk/Squeak centric \u0026ldquo;JSON\u0026rdquo;-kinda-thingy. I made Tirade in order to get a nice file format for Deltas. Just wanted to share how the first trivial code looks, and thus illustrate simple use of Tirade.\nI have a DSDelta (a Delta being almost like a ChangeSet). It consists of some metadata (a UUID, a Dictionary of properties and a TimeStamp) and a DSChangeSequence (which holds the actual DSChange instances). As a first shot I only implemented the metadata bit. So step by step:\nWrite a unit test, first let’s set up our readers and writers on a common stream:\nsetUp | stream | stream := RWBinaryOrTextStream on: String new. reader := DSTiradeReader on: stream. writer := DSTiradeWriter on: stream …then a trivial write, read and compare test - note that they both look at the same stream:\ntestEmptyDelta | delta same | delta := DSDelta new. writer nextPut: delta. reader reset. same := reader next. self assert: same = delta. self assert: delta timeStamp = same timeStamp. self assert: delta properties = same properties. self assert: delta uuid = same uuid Create DSTiradeWriter. It turns out that DSTiradeWriter at this point is just an empty subclass of TiradeRecorder! Eventually we might need to add behaviors but at this point there is no need. The TiradeRecorder uses DNU to intercept messages and encode them as Tirade.\nImplement #tiradeOn: in our domain object DSDelta. This will be used by the writer and looks like this:\ntiradeOn: recorder recorder delta: uuid asString36 stamp: timeStamp printString properties: properties …here we convert the UUID to a String (base 36) and the timeStamp too. The properties Dictionary just holds \u0026ldquo;simple\u0026rdquo; data that Tirade can represent, so no need to convert it. The rule is that we make up a message (in this case #delta:stamp:properties:) which will be used in the Tirade stream, and we make sure our arguments are \u0026ldquo;Tirade proper\u0026rdquo; which basically means Booleans, Strings, Symbols, Arrays, Numbers, Associations and Dictionaries thereof. Note that the recorder being a DSTiradeWriter inherits the implementation of #doesNotUnderstand: from TiradeRecorder that will write this Tirade message onto the stream typically looking like this:\ndelta: 'd71oknvt1bwswhno6iwgund07' stamp: '20 April 2009 11:20:50 am' properties: nil. And then the final step, our reader:\nCreata a DSTiradeReader. We simply create an implementation of the above Tirade message #delta:stamp:properties: and put it in the method category \u0026ldquo;tirade\u0026rdquo; so that the default security mechanism is happy:\ndelta: uuidString36 stamp: timeStampString properties: properties result := DSDelta new. result uuid: (UUID fromString36: uuidString36); properties: properties; timeStamp: (TimeStamp fromString: timeStampString) …this class inherits an instvar called ‘result’, which is fine to reuse. As you see the properties needs no conversion, the others are converted from Strings.\nAnd tada - the unit test is green! So we implemented reading and writing in more or less two lines of code. Kinda neat! :)\n"},{"title":"Tirade, part 2","permalink":"https://goran.krampe.se/2009/03/20/tirade-part-2/","summary":"\u003cp\u003eIn an article recently I described \u003ca href=\"http://goran.krampe.se/2009/03/16/tirade-a-file-format-for-smalltalkers/\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eTirade\u003c/a\u003e\n - a new generic \u0026ldquo;file format\u0026rdquo; for Smalltalk/Squeak, or actually a sub language! Since that article I have refined Tirade a bit. Tirade consists today of 4 classes (parser, reader, writer, recorder) totalling \u003cstrong\u003eabout 500 lines of code\u003c/strong\u003e, excluding tests. Tests are \u003cstrong\u003egreen in 3.10.2, pharo-10231, 3.9, 3.8 and 3.7\u003c/strong\u003e. It does turn red in 3.6 due to old initialize behavior, some missing methods etc, probably easily fixed if anyone cares. There are no dependencies on other packages. Compared to using the old Compiler\u0026raquo;evaluate: it is about 5-7 times faster.\u003c/p\u003e","content":"In an article recently I described Tirade - a new generic \u0026ldquo;file format\u0026rdquo; for Smalltalk/Squeak, or actually a sub language! Since that article I have refined Tirade a bit. Tirade consists today of 4 classes (parser, reader, writer, recorder) totalling about 500 lines of code, excluding tests. Tests are green in 3.10.2, pharo-10231, 3.9, 3.8 and 3.7. It does turn red in 3.6 due to old initialize behavior, some missing methods etc, probably easily fixed if anyone cares. There are no dependencies on other packages. Compared to using the old Compiler\u0026raquo;evaluate: it is about 5-7 times faster.\nTirade is a very small \u0026ldquo;language\u0026rdquo; similar to JSON (see below) and probably fits similar use cases as JSON fits.\nNumbers Link to heading In my first Tirade description I opted out and only supported plain integers, no frills at all. Then after subsequent discussion I came to the conclusion that syntactically there is no problem to letTiradeParser\u0026raquo;parseInteger become TiradeParser\u0026raquo;parseNumber and just let it handle all kinds of Number literals that Squeak supports by either using SqNumberParser if present (in Squeak 3.9+) or by falling back on regular old Number class\u0026raquo;readFrom: which Scanner still uses in 3.10.2.\nSo now Tirade deals perfectly fine with:\n23.45 (Floats)\n16rFE (radix)\n1.0034e-5 (scientific notation)\n243s2 (scaled decimals)\n\u0026ldquo;NaN\u0026rdquo;, \u0026ldquo;Infinity\u0026rdquo; and \u0026ldquo;-Infinity\u0026rdquo;\n…and whatever else should be there.\nThe performance penalty if we use SqNumberParser (Squeak 3.9+) is not that bad, about 20% on my little trivial benchmark. Using Number class\u0026raquo;readFrom: hurts more, increasing time for benchmark around 50%.\nSecurity… Link to heading First I played with having the builder object (that is typically fed the Tirade messages from the Tirade reader) implement isSelectorAllowed: etc. I finally ended up encoding a simple security scheme in the default TiradeReader that relies on finding the implementations of the Tirade messages in the builder in a method category beginning with \u0026ldquo;tirade\u0026rdquo;. It seems simple enough for most uses.\nI also added a global \u0026ldquo;whitelist\u0026rdquo; of Tirade messages that can be registered in the reader before starting to parse. If selectors are found in this whitelist they are considered \u0026ldquo;ok\u0026rdquo;. This can be useful in some situations.\nIf the builder relies on catching Tirade messages using doesNotUnderstand: then it is on its own for security, but that seems fine.\nFinally you can turn off all selector checks by using #unsafe:.\nReceiver juggling Link to heading Tirade is meant to separate \u0026ldquo;concerns\u0026rdquo; between Tirade \u0026ldquo;code\u0026rdquo;, parser, reader and the builder object supplied by you. The Tirade \u0026ldquo;code\u0026rdquo; has no control over the receiver of the messages, Tirade \u0026ldquo;code\u0026rdquo; is just a sequential flow of messages separated with periods. The TiradeParser also doesn’t care, it just parses and then does \u0026ldquo;self processMessage\u0026rdquo;, if you are using TiradeParser directly it has a default implementation of #processMessage that prints them out in Transcript and collects them in an OrderedCollection.\nSo yes, you can use TiradeParser to just gobble up some Tirade input and then muck about with the OrderedCollection afterwards - similar to how you work with JSON or an XML DOM. But the better approach is of course to subclass TiradeParser and implement #processMessage to actually do something - in a streaming SAX-ish fashion.\nThen we have the reader. There is a default TiradeReader that implements the security described above and also implements logic for deciding the \u0026ldquo;next receiver\u0026rdquo; of the Tirade messages. The logic goes like this:\nIf the builder supplied implements Tirade messages by always returning self, it will always be the receiver. Simple.\nIf the builder returns another object X, X will be used as the \u0026ldquo;next receiver\u0026rdquo;.\nAs long as X returns self it stays as the \u0026ldquo;next receiver\u0026rdquo;.\nIf object X returns another object Y, X will be put on a \u0026ldquo;stack of old receivers\u0026rdquo; and Y will be used as the \u0026ldquo;next receiver\u0026rdquo;.\nIf Y returns nil, X will be popped and be used as the \u0026ldquo;next receiver\u0026rdquo;.\nIf X returns nil we are back to the original builder, and if it returns nil nothing changes.\nSo if the above is \u0026ldquo;enough\u0026rdquo; for controlling the receivers, then the builder object handles it by simply returning the \u0026ldquo;right\u0026rdquo; objects. These objects can of course be \u0026ldquo;sub builders\u0026rdquo; or domain objects themselves or whatever.\nIf the above is not enough you can register \u0026ldquo;control messages\u0026rdquo; in TiradeReader. A control message can be any selector and will result in TiradeReader pushing the current receiver on the stack and setting the original builder object as the \u0026ldquo;next receiver\u0026rdquo;. There is also a small twist, if the control message returns self the reader will consider that to be equivalent to \u0026ldquo;nil\u0026rdquo; and thus pop the previous receiver back. This is because the common use is to make sure all control messages are sent to the original builder without disrupting the current stack of receivers. But… why? This enables the builder to explicitly control the reader during the parse, perhaps manipulating the current stack, even though it is not the \u0026ldquo;next receiver\u0026rdquo; receiving the regular Tirade stream of messages.\nOne very good reason to use this is when the current receiver is a domain object that does not \u0026ldquo;know\u0026rdquo; when to return nil to pop itself.\nI am not perfectly happy with the current mechanisms, but it will do for now and I will revisit this when I see how it works out in practice. The important bits are in place though - Tirade input has no control over receivers and the builder object can control it if needed.\nCompared to JSON again Link to heading The differences compared to JSON that I see right now:\nSmalltalk syntax and parsing rules for Strings. This means no escapes except for double-single quotes. JSON has 8 other escape codes. Immediate advantage for me is able to store readable code in Tirade, including newlines.\nSmalltalk syntax for Numbers. This means more capabilities for parsing numbers than JSON has (radix, NaN, Infinity, scaled decimals).\nSymbols. JSON only has Strings.\nAssociations. JSON has an \u0026ldquo;object\u0026rdquo; which is a Dictionary restricted to String keys. JSON does not have a free standing Association. In Tirade any of the allowed objects can of course be keys or values and Assocations can be \u0026ldquo;standalone\u0026rdquo;. So there is a little bit of greater flexibility here.\nComments. Hmmm, JSON has no comments. Tirade allowed Smalltalk comments, but ONLY between messages.\nMessages. This is the big difference, Tirade consists of a sequence of unary or keyword messages, with the \u0026ldquo;data\u0026rdquo; described above as arguments.\nThe addition of messages adds an important extra level of \u0026ldquo;classification\u0026rdquo;, \u0026ldquo;control\u0026rdquo; or \u0026ldquo;typing\u0026rdquo; or call it what you want. It also lends Tirade to easy streaming and concatenation. JSON consist on its top level of either a Dictionary or an Array. A parser could of course parse that in a \u0026ldquo;streaming fashion\u0026rdquo; one element or pair at a time, but they normally don’t do that I think.\nHaving messages of course makes it much more natural to map these messages onto a builder or multiple builders and also to use messages to control the message flow. I think this makes Tirade much more expressive in itself.\nIn summary, Tirade is similar to JSON but extended with messages and comments, more advanced Numbers, deals with text more easily (no escaping of CRs etc), can have comments in it, has a little bit more flexibility in data model (Associations) and uses Smalltalk syntax for it all.\nPotential uses for Tirade Link to heading I started out with a focus on replacing \u0026ldquo;chunk format\u0026rdquo; with something simpler and secure for Deltas (Deltastreams project), eliminating the use of Compiler to parse it. Afterwards one can find several interesting places where Tirade could be used for example:\nDSLs\nRPC-ish communication\nTransaction logs\n…and a few more things :)\nBut hey, one thing at a time.\n"},{"title":"Tirade, a file format for Smalltalkers","permalink":"https://goran.krampe.se/2009/03/16/tirade-a-file-format-for-smalltalkers/","summary":"\u003cp\u003eIn my revived work on \u003ca href=\"http://wiki.squeak.org/squeak/6001\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eDeltastreams\u003c/a\u003e\n in Squeak I ended up facing the choice of native file format for Deltas. Matthew has made an advanced format called \u003ca href=\"http://www.squeaksource.com/InterleavedChangeSet.html\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eInterleavedChangeset\u003c/a\u003e\n which manages to squeeze a binary representation of a Delta into a \u003ca href=\"http://wiki.squeak.org/squeak/1105\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eChangeset\u003c/a\u003e\n file (which is in Smalltalk chunk format). An impressive feat, and it has the advantage of being backwards compatible in the sense that a Delta in this format can be filed in as a plain old Changeset into an old Squeak image.\u003c/p\u003e","content":"In my revived work on Deltastreams in Squeak I ended up facing the choice of native file format for Deltas. Matthew has made an advanced format called InterleavedChangeset which manages to squeeze a binary representation of a Delta into a Changeset file (which is in Smalltalk chunk format). An impressive feat, and it has the advantage of being backwards compatible in the sense that a Delta in this format can be filed in as a plain old Changeset into an old Squeak image.\nBut I must say I don’t think that benefit alone is enough to justify these tricks. Oh well, time will tell - and multiple formats for Deltas are fine to have.\nLooking at another file format for Deltas I decided I want these properties:\nReadable. Changesets are nice because they are indeed readable. You can look at them in emacs if you like.\nEditable. Same here, if you really need to you can edit changesets manually. The syntax is not totally bad.\nSecure. Ouch, changesets fail here because they rely on Compiler\u0026raquo;eval: which of course opens up tons of tricks you can do. I don’t want that with Deltas.\nDeclarative. This is a spectrum but I would like the \u0026ldquo;style\u0026rdquo; for the file format to be declarative.\nStreamable. The parser should not have to read it all into a \u0026ldquo;DOM structure\u0026rdquo; before actually doing something with it.\nExtendable. It should be easy to extend the format in the future and have older code \u0026ldquo;ignore\u0026rdquo; such extensions.\nFast. It should be fast to parse and fast to produce. As always. :-)\nSmall. I mean both conceptually (easy to understand), codewise (parser etc) and syntactically.\nJSON or YAML Link to heading First I looked at JSON which nails 5-6 out of these 8. It is indeed \u0026ldquo;Readable\u0026rdquo;, \u0026ldquo;Editable\u0026rdquo;, \u0026ldquo;Secure\u0026rdquo;, \u0026ldquo;Fast\u0026rdquo; and \u0026ldquo;Small\u0026rdquo;. And it is very \u0026ldquo;hip\u0026rdquo; in the web arena. It suffers from some problems though:\nStrings can not have CRs in them, which will make \u0026ldquo;larger texts\u0026rdquo; such as source code a pure pain to read. This is a killer! Sorry.\nIt is actually not so well suited for streaming. A JSON document is a single \u0026ldquo;thing\u0026rdquo;, either a Dictionary or an Array. Sure, we could use convention and parse one key-value-pair (or element if it is an Array) at a time, but then I would need to write a new parser anyway.\nIt is declarative since it is \u0026ldquo;just data\u0026rdquo; but on the other hand this means it also lacks semantics. We would need to use Strings and keys (in key-value pairs) to denote our own semantics. Works, but probably would make the structure less apparent.\nSame goes for extendability. Sure, we can add new keys in our key-value pairs etc, but what we really want is to be able to add new semantic elements, and again, those would need to be \u0026ldquo;encoded as data\u0026rdquo; in JSON. I think it would get messy.\n…so JSON is out. I do like JSON though, in its utter simplicity and above all - it is available everywhere.\nWhat about YAML then - JSON’s big brother? YAML is a superset of JSON, well, it aims to be a strict superset at least. I did find a very good blog article comparing them. Looking at YAML it seemed to have lots of better ways to represent source code with CRs etc, but hey… simple? Mmmm, not. Sure, it may be \u0026ldquo;simple\u0026rdquo; to look at but I sure didn’t think the specification was simple and in fact HUGE and I had a hard time reading it due to its style. Sorry, not \u0026ldquo;small\u0026rdquo; enough for me! ;-)\nWhen discussing all this on squeak-dev the good ole \u0026ldquo;Hey, why not Smalltalk?\u0026quot;-mantra popped up. I have been there lots of times, using Smalltalk as \u0026ldquo;representation language\u0026rdquo; is very neat since it enables so called \u0026ldquo;internal DSLs\u0026rdquo; at such ease, but it does fail pretty hard on \u0026ldquo;Secure\u0026rdquo;, \u0026ldquo;Declarative\u0026rdquo; (depends on how you view that one, I know), \u0026ldquo;Streamable\u0026rdquo; and in some ways \u0026ldquo;Small\u0026rdquo;. Although it would be strange if we didn’t have Compiler available when dealing with Deltas :-).\nSmalltalk… or Angry Smalltalk? Link to heading But bringing it up did get my mind working - how about a nice subset of Smalltalk? That does what JSON does but fixes the problems I identify above? Pretty quickly a subset of Smalltalk crystallized itself that I named \u0026ldquo;Tirade\u0026rdquo; as in:\n\u0026ldquo;a long angry speech or scolding. Synonyms: diatribe, harangue, rant\u0026rdquo;\nTirade, as the name somewhat implies, is just a sequence of Smalltalk unary or keyword messages with optional Smalltalk comments inbetween.\nThe only thing making Tirade NOT a strict syntactic subset of Smalltalk is that there is no receiver to the left, this is up to the reader/parser to decide. One seemingly useful pattern for determining the receiver is to use the result of each message as the next receiver.\nHere is a fantasy example of Tirade input:\n\u0026quot;We allow unary messages, the period after each message is mandatory. A unary message is probably used mainly for semantic structure.\u0026quot; beginWumpus. \u0026quot;We allow Symbols.\u0026quot; push: #superbat. \u0026quot;Whitespace is just fine, so indentation can be used, but has no meaning. In Strings we use double single quote for a single quote. No other escaping exists.\u0026quot; name: 'Bat from hell' description: 'Black as devil''s tar, evil. Appear in flocks and when they come you better duck. Duck fast.'. \u0026quot;Integers are fine, positive or negative. No scientific notation, no floats.\u0026quot; power: 'Can screech' damage: 3. power: 'Can bite' damage: -6. attrib: #size-\u0026gt;43. attrib: #color-\u0026gt;nil. attrib: #dangerous-\u0026gt;true. moreattribs: { #wings-\u0026gt; 2 . #ears -\u0026gt; nil. #teeth -\u0026gt; {'one'.'two'.'three'}}. pop: #superbat. endWumpus. Well, you get the idea. So source code with CRs will work fine, just like in Changesets. We could even add support for indenting Strings with embedded CRs (as you can see above they otherwise break indentation), but I haven’t done that. So we have Strings, Integers, Associations, true/false/nil and brace Arrays. Nested in any combination and depth. In Smalltalk all these are \u0026ldquo;literals\u0026rdquo; except Associations which are actually created using the message #-\u0026gt; sent to the key object. In Tirade it is not implemented \u0026ldquo;as a message\u0026rdquo;, but rather built into the parser. I also chose the \u0026ldquo;brace array\u0026rdquo; instead of a regular array because it has separating periods and it allows Associations inside it.\nOk, so Tirade is just a sequence of messages with \u0026ldquo;data\u0026rdquo; as arguments. And the \u0026ldquo;data\u0026rdquo; is expressed very similarly to JSON, but with Smalltalk syntax. Is this better than plain JSON? I think so:\nWe got rid of the \u0026ldquo;CR in Strings\u0026rdquo;-issue, Tirade Strings are just like Smalltalk Strings - the only escape character is doubling a single quote.\nTirade is streaming since we parse and process the messages \u0026ldquo;one by one\u0026rdquo; and we get IMHO better \u0026ldquo;semantics\u0026rdquo; in the form of having something more than \u0026ldquo;just data\u0026rdquo;: keyword messages.\nExtending is easily done with new messages that old code can happily ignore at will - or capture using #doesNotUnderstand: and log or whatever.\nI just created the Squeaksource project Tirade for this, the code there has both reader, writer and green tests. It also has nice class comments :-) and it is not rocket science to get going with. The parser is a simple \u0026ldquo;predictive recursive descent\u0026rdquo; parser which anyone should be able to step through and understand. It has no ambiguity and it only checks the next Character for choice of production, which made it very easy to create.\nAre we there? Link to heading Did we meet our objectives we started out with? Do we have our \u0026ldquo;dream format\u0026rdquo; we want? Let’s look at it again:\nReadable. Oh yes, and for a Smalltalker VERY readable. We have simplicity, comments, indentation, CRs inside Strings etc.\nEditable. Definitely, for a Smalltalker VERY editable. It is Smalltalk after all.\nSecure. Very secure. There are no expressions and no access to globals. You can only send messages with data as arguments. You do not decide the receiver, the reader does. The base reader also does a security check asking the builder if it allows the selector.\nDeclarative. Given only messages (which creates structure and semantics) with data and no full Compiler I think it is very declarative.\nStreamable. Yep. We just keep going and going! Since the period is mandatory after a message this also means you can concatenate Tirade streams together without syntactic problems.\nExtendable. Just add new kinds of messages, make sure the old code can ignore \u0026ldquo;new messages\u0026rdquo; either by having a tolerant #doesNotUnderstand: or by letting #isSelectorAllowed: not allow unknown messages, which then will not be sent at all.\nFast. My first benchmark shows TiradeParser is about 7 times faster than Compiler. It is pretty nippy.\nSmall. It is definitely small in all aspects mentioned.\nJust one gripe… Link to heading Why is it not a true subset of Smalltalk - in other words, why did I leave out the receiver to the left?!? Well, since we don’t have any kind of variables there is not much you can put there! Should we still write out \u0026ldquo;self\u0026rdquo;? If we did, then it would be confusing if the reader uses the \u0026ldquo;result of message is the next receiver\u0026rdquo;-logic.\nWe could encode that policy by enforcing the code to say \u0026ldquo;me := me \u0026rdquo;, but then we would need to introduce a special variable \u0026ldquo;me\u0026rdquo; and it would look hackish and odd and confusing as hell. And it would also force this logic. I think leaving receiver out is ok. :-)\nSo why do we so dearly want to make it BE Smalltalk? In theory it could enable us to select some Tirade code with the mouse and press \u0026ldquo;alt-d\u0026rdquo; on it, but it is still quite easy to debug Tirade code directly. If someone makes a compelling argument I am willing to listen, but for now - sorry, no, Tirade is not == Smalltalk and it does not have an explicit receiver on the left. As Jecel pointed out though, it may be legal Self code. :-)\nConclusion Link to heading I think Tirade has interesting potential, especially as a readable serialization or configuration (!) format for Smalltalk. For \u0026ldquo;data interchange\u0026rdquo; JSON is probably still KING because then you often need to send data across language barriers and there are JSON parsers everywhere. Tirade is a Squeak only thing, although should be trivially portable to other Smalltalks.\nI now intend to go full steam ahead and use Tirade as a file format for Deltas in the DeltaStreams project. We will see how it turns out when put to some real world usage.\n"},{"title":"","permalink":"https://goran.krampe.se/2009/01/01/","summary":"\u003ch1 id=\"the-guts-of-ni\"\u003e\n  The guts of Ni\n  \u003ca class=\"heading-link\" href=\"#the-guts-of-ni\"\u003e\n    \u003ci class=\"fa-solid fa-link\" aria-hidden=\"true\" title=\"Link to heading\"\u003e\u003c/i\u003e\n    \u003cspan class=\"sr-only\"\u003eLink to heading\u003c/span\u003e\n  \u003c/a\u003e\n\u003c/h1\u003e\n\u003cp\u003eThis article describes parts of the current design and implementation of the Ni language. It\u0026rsquo;s not a tutorial, introduction or manual. It\u0026rsquo;s in fact kinda incoherent - but so is Ni :)\u003c/p\u003e\n\u003ch2 id=\"the-parser\"\u003e\n  The parser\n  \u003ca class=\"heading-link\" href=\"#the-parser\"\u003e\n    \u003ci class=\"fa-solid fa-link\" aria-hidden=\"true\" title=\"Link to heading\"\u003e\u003c/i\u003e\n    \u003cspan class=\"sr-only\"\u003eLink to heading\u003c/span\u003e\n  \u003c/a\u003e\n\u003c/h2\u003e\n\u003cp\u003eThe \u003ca href=\"https://github.com/gokr/ni/blob/master/src/niparser.nim\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003eNi parser\u003c/a\u003e\n is a straight forward hand made \u003cdel\u003erecursive descent\u003c/del\u003e parser. Hmmm, now that I look closer I realize its not recursive! Its just a very simple \u003ca href=\"https://github.com/gokr/ni/blob/master/src/niparser.nim#L477\"  target=\"_blank\" rel=\"noopener noreferrer\"\u003ewhile loop character by character\u003c/a\u003e\n and maintaining some state. It should be easy to read and understand and given that the grammar is so simple, it hasn\u0026rsquo;t changed much lately. It could probably be made faster by using more procs and less methods, but it\u0026rsquo;s probably plenty fast since the grammar is so simple.\u003c/p\u003e","content":" The guts of Ni Link to heading This article describes parts of the current design and implementation of the Ni language. It\u0026rsquo;s not a tutorial, introduction or manual. It\u0026rsquo;s in fact kinda incoherent - but so is Ni :)\nThe parser Link to heading The Ni parser is a straight forward hand made recursive descent parser. Hmmm, now that I look closer I realize its not recursive! Its just a very simple while loop character by character and maintaining some state. It should be easy to read and understand and given that the grammar is so simple, it hasn\u0026rsquo;t changed much lately. It could probably be made faster by using more procs and less methods, but it\u0026rsquo;s probably plenty fast since the grammar is so simple.\nThe parser constructs an AST consisting of instances of subclasses of Node . A Node is a regular \u0026ldquo;ref object\u0026rdquo; which is Nim terminology for a GC controlled object allocated on the heap. Its worth noting that the parser can be used alone without the interpreter, but the ni module (the interpreter) obviously depends on the parser module.\nNodes, Nodes\u0026hellip; Link to heading In Ni everything is a Node, but they come in different families:\nValues - fundamental \u0026ldquo;things\u0026rdquo; typically represented internally by the corresponding Nim type Words - the bread and butter of Ni, kinda like Smalltalk Symbols but have different prefixes making them behave differently Composites - the three base collections of Ni: Blocks, Contexts (Context not implemented yet) and Parens. Derived composites - these are created from a Composite, like a Func or an Object (Object not implemented yet). Values in Ni are not Ni objects (although they are indeed Nim objects) like in Smalltalk. They can instead be viewed as fundamental datatypes, but the Ni interpreter is designed so that you can add more of these in separate extension modules.\nWords are pervasive in the language, just like messages are pervasive in Smalltalk. They are kinda like variables in other languages, but using different prefixes the word behaves differently.\nComposites are fundamental collections and they are supported by specific literal syntax in the parser, [], {}, ().\nFinally, derived Composites are things one can create using a Composite as input. A Func is a function and it\u0026rsquo;s created from a Block. Objects are yet to be implemented.\nValues Link to heading All atomic values are wrapped using one subclass of Node for each kind, and currently we have: int, float, string, bool and nil. The values true, false and nil are represented with three singleton Values that are held by the interpreter. Those three singletons are bound to the words true, false and nil in the root context, which is the global namespace.\nNew kinds of values can relatively easily be added to Ni since I intentionally made the parser be pluggable for this. However I do not like the abundance of builtin types that Rebol/Red has, it feels like a mistake to hardwire so much into the language itself. But this way we are free to experiment with such extension modules.\nWords Link to heading Ni uses the term \u0026ldquo;word\u0026rdquo; much like Rebol does. There are however quite a few differences in what kinds of words Ni supports. A word is just a string, but it\u0026rsquo;s wrapped in a Word node and there are a number of different subclasses of Word which behaves differently and use different prefixes.\nEvalWord: The most common kind of word, no prefix. All eval words delegates evaluation to whatever it is bound to. In this way they act much like variables do in most other languages. LitWord: A literal word. Uses the '-prefix and is used when one wants to refer to the word as a value itself. Evaluates to itself. GetWord: Uses the ̂^-prefix. The get words do not delegate evaluation, instead they skip evaluation and \u0026ldquo;evaluate\u0026rdquo; to whatever it is bound to. EvalArgWord: Used to \u0026ldquo;pull in\u0026rdquo; arguments to Funcs, uses :-prefix. Evaluates the argument in the callsite context and pulls in the result, this is like \u0026ldquo;normal\u0026rdquo; argument passing in most languages. GetArgWord: Uses the :^-prefix and evaluates to the argument itself, the AST node. No evaluation of the node is made. This enables Ni functions to manipulate the AST. All words (well, currently only EvalWords and GetWords, but I should make it work for ArgWords and LitWords too) can also, just before the word itself, be additionally prefixed with . or ... This affects lookup and is similar to how one refers to the current or parent directory in Unix. The rules I have in mind currently goes like this:\n..x: assignment and lookup is in the nearest outer lexical environment only. .x: assignment and lookup is in the local context only. x: assignment and lookup is in the local context, but lookup continues outward to the surrounding lexical environment and beyond. I have been mulling these rules over, but I think this logic would make it fairly reasonable.\nComparing with Rebol. As far as I know the . and ..-prefixes does not have a counterpart in Rebol. Rebol has get words and eval words, but uses :-prefix instead of ^-prefix for get words. The reason Ni deviates is to use : for arg words instead, mimicking Smalltalk block syntax. Rebol does not have arg words at all, but Rebol does have set words which Ni does not have (again to support keywords). Ni instead implements assignment as a primitive infix function.\nI also experimented earlier with bindings etc, but currently Ni doesn\u0026rsquo;t work like that. Exactly how different environments can be used dynamically - is still an open design question. Scoping is however mainly lexical but I can imagine mechanisms to control this, and also reification mechanisms in order to reflect on and manipulate the activation record spaghetti stack.\nComposites Link to heading There are three different composites in Ni, each formed by literal syntax [], () and {} respectively. These are called Blocks, Parens and Contexts.\nBlock and Paren is a wrapped seq of Nodes, seq being the dynamic array type of Nim. Currently they differ only in behavior since Parens evaluate by evaluating its child nodes one by one and returning the last result. Blocks just evaluate to themselves. To evaluate a Block as code you need to explicity do so using the do word.\nContexts are being implemented. A Context has a Nim Table internally making it the fundament of both objects and \u0026ldquo;Dictionaries\u0026rdquo;, much like in Javascript.\nObjects are being implemented and are fundamentally like Contexts, but with special evaluation behavior.\nRelying on Nim Link to heading The Ni interpreter tries to be very simple and reuses as much of Nim\u0026rsquo;s machinery as possible:\nA call in Ni results in a call in Nim. This means Ni maintains no call stack of its own. Ni has no memory model of its own, we use Nim\u0026rsquo;s very capable garbage collected memory model. Ni is a plain interpreter, not a JIT. The emphasis is instead on hackability, portability but also very much mixing with Nim. Ni primitives are Nim procs. It\u0026rsquo;s very easy to bind words to primitive procs in Nim. Dynamic dispatch in Ni (for Values) relies on dynamic dispatch in Nim, methods. Multiple dispatch is also used for number coercions and similar. Nim has very strong macro mechanisms which I hope to eventually use to generate glue code to expose Nim libraries in Ni. The things described in this article tend to evolved from day to day, but hopefully this better explains a bit about how Ni is constructed.\n"},{"title":"Archive","permalink":"https://goran.krampe.se/archive/","summary":"","content":""},{"title":"Evothings","permalink":"https://goran.krampe.se/evothings/","summary":"","content":""},{"title":"Search","permalink":"https://goran.krampe.se/search/","summary":"","content":""}]