{"id":329,"date":"2007-03-02T11:15:21","date_gmt":"2007-03-02T11:15:21","guid":{"rendered":"http:\/\/scientopia.org\/blogs\/goodmath\/2007\/03\/02\/clear-object-oriented-programming-not-in-glass\/"},"modified":"2007-03-02T11:15:21","modified_gmt":"2007-03-02T11:15:21","slug":"clear-object-oriented-programming-not-in-glass","status":"publish","type":"post","link":"http:\/\/www.goodmath.org\/blog\/2007\/03\/02\/clear-object-oriented-programming-not-in-glass\/","title":{"rendered":"Clear Object-Oriented Programming? Not in Glass"},"content":{"rendered":"<p> Todays bit of programming insanity is a bit of a novelty: it&#8217;s an object-oriented programming language called <a href=\"http:\/\/www.esolangs.org\/wiki\/Glass\">Glass<\/a>, with an interpreter available <a \/>here<\/a>. So far in all of my Friday Pathological Programming columns, I haven&#8217;t written about a single object-oriented language.  But Glass is something<br \/>\nspecial. It&#8217;s actually sort of a warped cross between Smalltalk and Forth &#8211; two things that should <em>never<\/em> have gotten together; in the words of the language designer, <a href=\"http:\/\/www.esolangs.org\/wiki\/Gregor_Richards\">Gregor Richards<\/a>, &#8220;No other language is implemented like this, because it would be idiotic to do so.&#8221;<\/p>\n<p><!--more--><\/p>\n<p> In general, Glass using single character identifiers and commands. To use any multiple character identifier, you need to wrap it in parens. So, for example, &#8220;a&#8221; is an identifer; &#8220;abc&#8221; is three identifiers &#8211; a, b, and c; &#8220;(abc)&#8221; is a single identifier. This has the interesting effect of making the language considerably harder to read, for absolutely no good reason.<\/p>\n<p> A program in Glass, like in most other object-oriented languages is a series of class definitions. A class declaration is enclosed in curly braces, and consists of a class name followed by a list of methods. Each method is enclosed in square brackets, and consists of a method name followed by a sequence of cmmands. So, for example, the &#8220;main program&#8221; in Glass is the method M of the class M; so a minimal Glass program is:<code>{M[m]}<\/code>: that&#8217;s a declaration of class &#8220;M&#8221;, which has one method, named &#8220;m&#8221;, which does nothing.<\/p>\n<p> Within Glass code, there are four different kind of variable:<\/p>\n<ol>\n<li> Global variables: generally used for class names, global variables have names that start with an upper-case letter.<\/li>\n<li> Instance variables: variables local to a particular object. Instance<br \/>\nvariables have names starting with a lower-case letter.<\/li>\n<li> Class variables: variables shared between all instances of a class. Class variables start with a lower-case letter. They look exactly like instance variables,<br \/>\nbut they&#8217;re accessed using a different operator.<\/li>\n<li> Local variables: variables local to a particular invocation of a method. Local variable names start with an &#8220;_&#8221;; since identifiers more than one character long must<br \/>\nbe enclosed in parens, <em>all<\/em> references to local variables must be enclosed in parens.<\/li>\n<\/ol>\n<p> The basic operators in Glass fall into three groups: object-oriented operators,<br \/>\nstack operators, and control-flow operators. I&#8217;ll use Forth notation for stack effects: (v1 v2 &#8211; v3 v4) means that the top of the stack before the operation consisted of the values v1 and v2 (with v2 on top); and after, the top values were v3 and v4.<\/p>\n<p> The object-oriented operators are:<\/p>\n<dl>\n<dt>Create object: <code>!<\/code> (varname global &#8211;)&#8221;<\/dt>\n<dd>Assumes that there are two identifiers on the stack &#8211; a global variable<br \/>\nreferring to a class, and any other kind of variable. An instance of the<br \/>\nclass named by the global is created, its constructor method (the method named &#8220;c__&#8221;) is called, and the result is assigned to the target variable.<\/dd>\n<dt>Retrieve method: <code>.<\/code> (object name &#8212; method)<\/dt>\n<dd>Retrieve the method named &#8220;name&#8221; for the object &#8220;object&#8221;, and push<br \/>\nit onto the stack.<\/dd>\n<dt>Assign self: <code>$<\/code> (name &#8212; )<\/dt>\n<dd>Assign the value of self to the variable whose name is on top of the stack.<\/dd>\n<\/dl>\n<p> The stack operators are:<\/p>\n<dl>\n<dt> Push variable name: <code>(name)<\/code> ( &#8212; name )<\/dt>\n<dd> Push a variable name onto the stack. The parens are only required if &#8220;name&#8221; is more than one character long.<\/dd>\n<dt>Copy stack value: <code>(number)<\/code> (s<sub>n<\/sub> s<sub>n-1<\/sub>&#8230;s<sub>0<\/sub> &#8212; s<sub>n<\/sub> s<sub>n-1<\/sub>&#8230;s<sub>0<\/sub> s<sub>n<\/sub>)<\/dt>\n<dd> Copy a value from the specified depth onto the top of the stack. The parens are only required in the number is more than one digit.<\/dd>\n<dt> Push a string: <code>\"string\"<\/code> ( &#8212; &#8220;string&#8221; )<\/dt>\n<dd> Push a string value onto the stack.<\/dd>\n<dt> Push a number: <code>&lt;number&gt;<\/code> ( &#8212; number)<\/dt>\n<dd> Push a numeric value onto the stack.<\/dt>\n<p>as a stack copy command.<\/dd>\n<dt> Drop: <code>,<\/code> (v &#8212; )<\/dt>\n<dd> Discard the top value from the stack.<\/dd>\n<dt> Retrieve variable value: <code>*<\/code>. (name &#8212; value)<\/dt>\n<dd> Retrieve the value of the variable whose name is on top of the stack.<\/dd>\n<\/dl>\n<p> And finally, the control flow operators are:<\/p>\n<dl>\n<dt>Return: <code>^<\/code><\/dt>\n<dd> Return from the current method call.<\/dd>\n<dt>Execute method: <code>?<\/code><\/dt>\n<dd> Pop the method on top of the stack, and execute it.<\/dd>\n<dt> Loop: <code>\/(name)commands<\/code><\/dt>\n<dd> While the variable named &#8220;name&#8221; has a non-zero or non-empty string value,<br \/>\nexecute the commands in the loop body.<\/dd>\n<\/dl>\n<p> There are also a set of built-in classes which contain basic operations:<\/p>\n<ul>\n<li> Class &#8220;A&#8221; contain arithmetic operations: A.a (add), A.s (subtract), A.m (multiply), A.d (divide), A.mod (modulo), A.f (floor), A.e (equality test), A.ne, A.lt, A.le, A.gt. A.ge (comparions).<\/li>\n<li> Class &#8220;S&#8221; contains string operators: S.l (length), S.i (character at index),<br \/>\nS.a (concatenate), S.d (divide string at a position), S.e (equality test),<br \/>\nS.ns (number to character conversion), S.sn (character to number conversion).<\/li>\n<li> Class &#8220;O&#8221; contains output operators: O.o (output string), O.on (output number).<\/li>\n<li> Class &#8220;I&#8221; contains input operators: I.l (input a line of text), I.c (input a character), I.e (check for end of file).<\/li>\n<\/ul>\n<p> So&#8230; Finally some sample programs. As usual, we start with Hello world:<br \/>\n<code><br \/>\n{M[m(_o)O!\"Hello world\"(_o)o.?]}<br \/>\n<\/code><\/p>\n<p> It looks awful, but it&#8217;s actually pretty easy. It instantiations class &#8220;O&#8221;, storing the instance in local variable (_o); then it pushes the string &#8220;Hello world&#8221; onto the stack; then it pushes the &#8220;o&#8221; method of our instance of &#8220;O&#8221; onto the stack and executes it.<\/p>\n<p> Now for something much more interesting; the Glass version of a Fibonacci sequence generator.<\/p>\n<pre>\n{F\n[f\n(_a)A!\n(_o)O!\n(_t)$\n(_n)1=,\n(_isle)(_n)*&lt;2&gt;\n(_a)(le).?=\n\/(_isle)\n&lt;1&gt;^\n\n(_n)\n*&lt;1&gt;(_a)s.?\n(_t)f.?\n(_n)*\n&lt;2&gt;(_a)s.?\n(_t)f.?\n(_a)a.?\n]\n}\n{M\n[m\n(_a)A!\n(_f)F!\n(_o)O!\n(_n)&lt;1&gt;=\n(_nlm)&lt;1&gt;=\n\/(_nlm)\n(_n)*\n(_f)f.?\n(_o)(on).?\n\" \"(_o)o.?\n(_n)(_n)*\n&lt;1&gt;(_a)a.?=\n(_nlm)(_n)*\n&lt;20&gt;(_a)(le).?=\n\n]\n}\n<\/pre>\n<p> That&#8217;s pretty long and cryptic, even with my efforts to format it cleanly. So let&#8217;s take it apart, bit by bit.<\/p>\n<ol>\n<li> It starts by declaring class &#8220;F&#8221;. &#8220;F&#8221; has one method, &#8220;f&#8221;:\n<ol>\n<li> &#8220;F.f&#8221; instantiates an A, and an O, and stores a reference to itself in (_t).<\/li>\n<li> It copies the value on top of the stack, and stores it in (_n). This is<br \/>\nthe number of the element of the fibonacci series that it&#8217;s trying to generate. <\/li>\n<li> It compares (_n) with 2 and stores the result in (_isle), and then if<br \/>\n_n was less than or equal to 2, it returns 1.<\/li>\n<li> Otherwise, it subtracts one from (_n), and gets that fibonacci number (f(n-1));<br \/>\nthe subtracts two from (_n), and returns that fibonacci number (f(n-2)), and then adds them together.<\/li>\n<\/ol>\n<\/li>\n<li> Then it defines a main method &#8211; class M, method m, which instantiates an &#8220;A&#8221;, an &#8220;F&#8221;, and an &#8220;o&#8221;; and loops through calling f for each number from 1 to 20.<\/li>\n<\/ol>\n<p> See? Not so hard!<\/p>\n<p> How about the infamous 99 bottles of beer? Without my help in reformatting<br \/>\nto make it legible?<\/p>\n<pre>\n{B[b&lt;99&gt;^]}{P[(c__)oO!t$aA!][n&lt;10&gt;s(ns).?oo.?][poo.?tn.?][b(_m)1=,(_x)&lt;0&gt;\n(_m)*ae.?=(_y)&lt;1&gt;=\/(_x)\"No more\"oo.?(_x)0=(_y)0=\/(_y)(_m)*o(on).?(_y)0=\n\" bottle\"oo.?(_x)&lt;1&gt;(_m)*ae.?=\/(_x)^(_x)0=\"s\"oo.?]}{C[(c__)oO!aA!sS!pP!t\n$][gn*][xn1=,][dnn*&lt;1&gt;as.?=][vn*pb.?\" of beer on the wall,n\"pp.?n*pb.?qe\n\" of beer,n\"pp.?\"Take one down, pass it aroundn\"pp.?ln*&lt;1&gt;as.?=l*pb.?wu\n\" of beer on the wall.nn\"pp.?pn.?]}{M[moO!cC!bB!bb.?cx.?fcg.?=\/fcv.?cd.\n?fcg.?=]}\n<\/pre>\n<p> That shouldn&#8217;t be too hard to figure out. The key is really just a question of formatting &#8211; once you separate it out so that it&#8217;s one statement per line, it&#8217;s remarkably easy to follow.<\/p>\n<p> Finally, I&#8217;ll close with a quine:<\/p>\n<p>\n{M[m(_s)S!(_o)0O!o.(_s)(ns).?&#8221;{M[m(_s)S!(_o)0O!o.(_s)(ns).?&#8221;<br \/>\n&#8220;14?24?14?24?24?04?24?04?]}&#8221;14?24?14?24?24?04?24?04?]}<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Todays bit of programming insanity is a bit of a novelty: it&#8217;s an object-oriented programming language called Glass, with an interpreter available here. So far in all of my Friday Pathological Programming columns, I haven&#8217;t written about a single object-oriented language. But Glass is something special. It&#8217;s actually sort of a warped cross between Smalltalk [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[92],"tags":[],"class_list":["post-329","post","type-post","status-publish","format-standard","hentry","category-pathological-programming"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p4lzZS-5j","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/329","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/comments?post=329"}],"version-history":[{"count":0,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/329\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/media?parent=329"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/categories?post=329"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/tags?post=329"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}