<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[goby-lang - Medium]]></title>
        <description><![CDATA[This is the official blog of Goby programming language - Medium]]></description>
        <link>https://medium.com/goby-lang?source=rss----d4fd60d99b7f---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>goby-lang - Medium</title>
            <link>https://medium.com/goby-lang?source=rss----d4fd60d99b7f---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 06 May 2026 15:39:13 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/goby-lang" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[No More Best Practices]]></title>
            <link>https://medium.com/goby-lang/no-more-best-practices-706664b7652?source=rss----d4fd60d99b7f---4</link>
            <guid isPermaLink="false">https://medium.com/p/706664b7652</guid>
            <category><![CDATA[goby]]></category>
            <category><![CDATA[programming-languages]]></category>
            <category><![CDATA[best-practices]]></category>
            <dc:creator><![CDATA[Stan Lo]]></dc:creator>
            <pubDate>Sat, 07 Oct 2017 14:41:36 GMT</pubDate>
            <atom:updated>2017-10-11T15:41:04.334Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*y3Tn_FY0zcD_dBAYXj2gNw.jpeg" /></figure><p>I’m a Rubyist, and just started writing Go several months ago. And at the beginning of learning Go, the most uncomfortable thing for me is that for most of the time, there is only one way to get things done.</p><p>For example, if you want to go through each elements in an array, you can only do it using the for keyword:</p><pre>for _, elem := range elements {<br>    // Do something<br>}</pre><p>In contrast, you can do this using several approaches in Ruby</p><pre>elements.each do |elem|<br>  # Do something<br>end</pre><pre>i = 0<br><br>while i &lt; elements.length do<br>  elem = elements[i]<br>  # Do something<br>  i += 1<br>end</pre><pre>for elem in elements do<br>  # Do something<br>end</pre><p>And I think most Rubyists will agree that using the first approach is the <strong>best practice</strong> for going through each elements in an array.</p><p>So here comes the keyword: <strong>best practice</strong>.</p><p>This means instead of just knowing how to do the task, the programmer should also know how to do it in a <strong>right way</strong>. But why do we provide so many approaches for doing one job to language users, but tell them to learn and use only one of the them?</p><p>If you give programmers too much options to do one thing, they need to learn all those options and remember the best one, which in a sense is increasing the learning cost of the language. Also, the community might spend time arguing about what is the <strong>best practice</strong>.</p><h4>Conclusion</h4><p>So from my perspective, a language should only provide the best practice to its users. Which means there will be no <strong>best practice</strong>, because there will only be one practice.</p><p>This can be done by reducing the types of statements, providing less builtin methods or having an official linter…etc. And this is why we don’t have the for statement in <a href="https://github.com/goby-lang/goby">Goby</a>. Because we can, and should only just use Array#each or Range#each if we want to do the task.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=706664b7652" width="1" height="1" alt=""><hr><p><a href="https://medium.com/goby-lang/no-more-best-practices-706664b7652">No More Best Practices</a> was originally published in <a href="https://medium.com/goby-lang">goby-lang</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Keep the stack clean]]></title>
            <link>https://medium.com/goby-lang/keep-the-stack-clean-3f4b79a438e0?source=rss----d4fd60d99b7f---4</link>
            <guid isPermaLink="false">https://medium.com/p/3f4b79a438e0</guid>
            <category><![CDATA[stack]]></category>
            <category><![CDATA[programming-languages]]></category>
            <category><![CDATA[compilers]]></category>
            <category><![CDATA[ruby]]></category>
            <category><![CDATA[goby]]></category>
            <dc:creator><![CDATA[Stan Lo]]></dc:creator>
            <pubDate>Fri, 04 Aug 2017 03:27:51 GMT</pubDate>
            <atom:updated>2017-08-04T05:22:55.116Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<h3>Keep The Stack Clean</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*o1pnCCcHNrg8Rz3p_UcfBQ.jpeg" /></figure><p>Most compilers should remove (or force you to remove) unused expressions, like the i in:</p><pre>5.times do |i|<br>  i &lt;- This should be removed<br>  puts(i)<br>end</pre><p>Because if we allow it being pushed on the stack, there’s no way we can remove it from the stack. For example, after the above program finishes, the stack would be like:</p><pre>  &lt;- Stack pointer<br>4<br>3<br>2<br>1<br>0</pre><p>So it’s just a matter of time the stack would be filled with those unused values.</p><h4>The solutions</h4><p>There are two solutions for this issue:</p><ul><li>Ignore those expressions in code generator</li><li>Pop each statement’s return value</li></ul><h4>Ignore those expressions in code generator</h4><p>This is the ideal approach for this issue, just skip the generation of those expressions.</p><p>But it’s actually more complicated to than that. Some expressions like string literal or boolean literal can be skipped without any hesitation. However, when the expression is an identifier, things get more complicated. If the identifier represents a local variable you should skip it, but if it&#39;s a method call you still need to generate the instructions and pop it&#39;s return value if needed.</p><p>Also, the assign expression and if expression are tricky to handle, too. Their instructions should always be generated, but the result can be different according to whether we need the return value or not. For example, the instructions of:</p><pre>if a &gt; b<br>  foo<br>end</pre><p>should be:</p><pre>0 getlocal 0 0<br>1 getlocal 0 1<br>2 send &gt; 1<br>3 branchunless 7 # Jump to leave if it’s false<br>4 putself<br>5 send foo 0     # If it’s true we call the method<br>6 pop            # And pop the return value of method foo<br>7 leave</pre><p>But if we assign it to a variable like:</p><pre>c = if a &gt; b<br>  foo<br>end</pre><p>the instructions would be:</p><pre>0 getlocal 0 0<br>1 getlocal 0 1<br>2 send &gt; 1<br>3 branchunless 7 # Returns nil if false<br>4 putself<br>5 send foo 0     # Call foo but not popping its return value<br>6 jump 8         # Skip the nil value<br>7 putnil         <br>8 setlocal 0 2<br>9 leave</pre><p>For setting local c, we need to make the if statement change to if expression. To do this we need to the result of foo method call and put an extra nil and the corresponding jump for false case.</p><p>So even though this solution is the better one but implementing it can be time consuming.</p><h4>Pop statement’s return value</h4><p>This is a relatively naive approach. We should prevent those value being push on the stack at first place instead of pushing them and then popping them.</p><p>But this is what Goby currently using because it’s easier to implement. We just need to literally pop every statement’s return value by default, and mark a few exceptions like the last statement in method body or the last statement in block argument to keep their value.</p><h4>Make sure the stack is clean</h4><p>Since keeping the stack clean is so important, we check the SP’s value (which should always be 1)after every test program’s execution. Currently our naive approach works quite well.</p><p>Note: The SP should be 1 instead of is0 because the stack should keep the last value of execution for comparing the result. This only happens when parser and code generator is in Test mode.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3f4b79a438e0" width="1" height="1" alt=""><hr><p><a href="https://medium.com/goby-lang/keep-the-stack-clean-3f4b79a438e0">Keep the stack clean</a> was originally published in <a href="https://medium.com/goby-lang">goby-lang</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Statements vs Expressions in Ruby]]></title>
            <link>https://medium.com/goby-lang/statements-vs-expressions-in-ruby-2166026784c4?source=rss----d4fd60d99b7f---4</link>
            <guid isPermaLink="false">https://medium.com/p/2166026784c4</guid>
            <category><![CDATA[goby]]></category>
            <category><![CDATA[statement]]></category>
            <category><![CDATA[programming-languages]]></category>
            <category><![CDATA[ruby]]></category>
            <category><![CDATA[expression]]></category>
            <dc:creator><![CDATA[Stan Lo]]></dc:creator>
            <pubDate>Mon, 31 Jul 2017 08:07:55 GMT</pubDate>
            <atom:updated>2017-10-14T13:56:32.099Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*ZTwgaPPT3yZQysr0cPrfjw.png" /></figure><p>Statements are declarations that can make up a line (or multiple lines). And expressions are operations which will return values. So expressions are also a kind of statements.</p><p>Commonly seen statements are:</p><ul><li>variable assignment</li><li>return statement</li><li>flow control keywords like break, continue</li><li>for loop</li><li>switch statement</li><li>while loop</li><li>if statement</li></ul><p>And common expressions are:</p><ul><li>built in data types 1, &quot;foo&quot;, true, null, [1, 2, 3]</li><li>objects</li><li>function call like add(1, 2)</li><li>variable like foo</li><li>arithmetic operation like 1 + 1 * 2</li><li>comparison like a == b, a &gt; c</li><li>self keyword in some languages</li><li>yield in Ruby</li></ul><p>So how do they compose a program? Let’s see an example:</p><pre>i = 0<br>while i &lt; 10 do<br>  i = i + 1<br>end<br>i</pre><p>And it’s structure is</p><pre>Statement(assign statement) { i = Expression(integer literal expression) [0] }<br><br>Statement(while loop statement) { <br>  while Expression(comparison expression) [i &lt; 10]  do<br>    Statement(assign statement) { i = Expression(arithmetic expression) [i + 0]<br>    }<br>  end<br>}<br><br>Statement(assign statement) { Expression(variable expression) [i] }</pre><h4>But in Ruby, things get more trickier</h4><p>In Ruby, sometimes statements can also be expressions under certain conditions, for example:</p><h4>assignment statement</h4><p>In a = a = b, the first assignment a = b is an expression and returns value of b. But a = a = b itself it&#39;s a statement, not an expression.</p><h4>if statement</h4><pre>a = if b &gt; c<br>      10<br>    end<br>puts(a) #=&gt; 10</pre><p>Whether these statements would change into expressions are determined by one thing: where are they placed.</p><p>Let’s take assign statement as example, it’s structure looks like this:</p><p>Variable = EXPRESSION</p><p>On the lefthand side of = is the variable we are assigning value to. And the righthand side of = must be an expression so we can have a value to assign.</p><p>Under this condition whatever statement you put in the righthand side would be an expression and returns a value. No matter it’s an assignment statement, if statement or even a class statement.</p><pre>a = class Foo; end<br>puts(a) #=&gt; nil<br><br>b = a = 10<br>puts(b) #=&gt; 10<br><br>c = if true<br>      100<br>    end<br>puts(c) #=&gt; 100</pre><p>Similar condition happens when the statement is treated as a function argument:</p><pre>puts(d = 1000) #=&gt; 1000</pre><h4>What about Goby?</h4><p>Since Goby is trying to make users feel like they are using Ruby, so we’re trying to port this behavior to Goby. But we only support this kind of Statement -&gt; Expression transition for If Statement and Assign Statement. Because we don’t usually need other statements’ return value. And actually those two statements are considered as expressions by default in Goby.</p><h4>The Implementation</h4><p>We do this by using a state machine in parser. When parser start parsing an assignment or a function call, it’ll enter a special state. Under this state the Assign Statement or If Statement would be treat like expression and we can get their return value.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2166026784c4" width="1" height="1" alt=""><hr><p><a href="https://medium.com/goby-lang/statements-vs-expressions-in-ruby-2166026784c4">Statements vs Expressions in Ruby</a> was originally published in <a href="https://medium.com/goby-lang">goby-lang</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Economics of Programming Languages]]></title>
            <link>https://medium.com/goby-lang/the-economics-of-programming-languages-5fe491f4e5?source=rss----d4fd60d99b7f---4</link>
            <guid isPermaLink="false">https://medium.com/p/5fe491f4e5</guid>
            <category><![CDATA[goby-lang]]></category>
            <category><![CDATA[golang]]></category>
            <category><![CDATA[goby]]></category>
            <category><![CDATA[programming-languages]]></category>
            <category><![CDATA[ruby]]></category>
            <dc:creator><![CDATA[Stan Lo]]></dc:creator>
            <pubDate>Sun, 30 Jul 2017 15:21:42 GMT</pubDate>
            <atom:updated>2017-07-30T15:48:59.650Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<h3>The Economic of Programming Languages</h3><h4>And why I insist on developing <a href="https://github.com/goby-lang/goby">Goby</a></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eO-ImcZM0z70J9L-km6s7A.jpeg" /></figure><h4>The costs of transferring to new language</h4><p>The main cost of transferring from A language to B language for a developer is time. The longer a developer spends on learning the new language, the higher it costs. So normally a new language seeks to avoid excessive syntax or characteristic, to lower the learning cost.</p><p>Rebuilding the ecosystem of language is also figured in the cost. In general, the number of early adopters for a new language erupting is not many, and learning resources or libraries for the new adopters are insufficient in most cases. For example, just assume a Rails developer wants to use <a href="https://github.com/goby-lang/goby">Goby</a> for his next project. Even if the cost of transferring from Ruby to <a href="https://github.com/goby-lang/goby">Goby</a> is not high, he or she still needs to give up Rails or other powerful libraries, and this will be a big concern for him or her.</p><h4>The attraction of transferring to new language</h4><p>But there still are many new languages being created constantly. And many developers also choose to use them despite the costs, why?</p><p>The major reason is that the features and the platforms developers using are constantly changing as the technology evolves. Like the invention of smart phone provides new a platform for developers, or the growing web traffic increases the need of highly concurrent programming languages.</p><p>Under this condition, new languages can be optimized for certain usage or platform. However, most conventional languages are too big and can’t effort breaking changes, so it’s nearly impossible or will take a lot of time for those languages to fulfill the needs. But developers still need to finish their tasks under time pressure, so they have no choice but to use newer languages to finish the job, or even completely migrate to newer languages.</p><h4>What about Goby?</h4><p>The above assumptions are the main reason I keep developing <a href="https://github.com/goby-lang/goby">Goby</a>. Choosing Ruby’s syntax and Object system is to reduce the entry cost; using Go as host language is for better concurrency support. So if <a href="https://github.com/goby-lang/goby">Goby</a> can bring sufficient improvements in performance (especially for microservices) and won’t cost them too much time to adapt it, it would be easy to attract them transferring to use <a href="https://github.com/goby-lang/goby">Goby</a>, just like Elixir did.</p><p><a href="https://github.com/goby-lang/goby">Goby</a>’s another opportunity is that there are still no mature frameworks for developing microservice. And due to the language’s design, there’re very few people use Ruby to write microservices. So when it comes to develop microservices, Ruby developers usually need to choose other languages, like Go. And since <a href="https://github.com/goby-lang/goby">Goby</a> is more easier to learn and provides higher efficiency in development than Go, it should have certain attractions for those them.</p><p>At this moment, <a href="https://github.com/goby-lang/goby">Goby</a> can already call/use functions or datas in Go Plugin like:</p><pre># p is a plugin object<br>p = import &quot;./plugins/plugin.go&quot;<br><br># we can call plugin&#39;s top level function directly<br>bar, err = p.send(&quot;NewBar&quot;, &quot;xyz&quot;) <br><br># we can also call Go object/pointer&#39;s method<br># the &#39;Add&#39; method&#39;s type is &#39;func(int, int64) int64&#39; so type transition is necessary (but easy to do)<br>r = bar.send(&quot;Add&quot;, 10, 100.to_int64) <br>puts(r) #=&gt; 110</pre><p>This means in the future <a href="https://github.com/goby-lang/goby">Goby</a> developer can use Go to write their extensions (I think it should be far more easier than writing C), and call those Go code directly using <a href="https://github.com/goby-lang/goby">Goby</a>&#39;s friendly syntax. Meanwhile, they can also use Go&#39;s libraries in those extensions, which would be very helpful.</p><p>Above points are the reason I still develop <a href="https://github.com/goby-lang/goby">Goby</a> in full time. But I’m still wondering if developers would choose it. We can only know that after <a href="https://github.com/goby-lang/goby">Goby</a>’s first release and my talk at RubyKaigi.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5fe491f4e5" width="1" height="1" alt=""><hr><p><a href="https://medium.com/goby-lang/the-economics-of-programming-languages-5fe491f4e5">The Economics of Programming Languages</a> was originally published in <a href="https://medium.com/goby-lang">goby-lang</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>