August 2nd, 2008

I’m pretty sure most Railers don’t think about this kind of thing, but controllers.. they are state machines. Sure, most controllers don’t have much state. They implement CRUD, which means the only state you need is the state of validness of your model. The control flow is directed by #valid?, with maybe a confirm message for #delete.

But shopping carts are not that simple, and probably shouldn’t be. You want to collect the user’s purchased items, their address, credit card, and then confirmation of it all. In that order. Making them create/read/update/delete an address, create/read/update/delete a credit card. Then having them add the address, credit card, and items to a Basket object. That’s just too many steps and anyone can tell that would be really silly as a user flow.

Could you reduce 95% of controller actions to just CRUD? Yes, you probably could. But that’s now how we think. Sometimes you need more than one step to produce a good user flow. Even with Ajax, you still sometimes want to reload the entire page, or allow older browsers to use the functionality easily.

No.. Controllers ought to be modeled after the user flow, not what’s easy (or hard) about the development process. The reason that web apps tend to be so simple is not because of some intuitive understanding of what the user wants.. And I’m sure that simple apps win over complicated ones any day. No. While I would rather write simple code, sometimes the domain model expects more. But we don’t have any off-the-shelf abstractions with which to go above the request/response cycle.

We need a plugin that can do this. We need an acts_as_state_machine for controllers. I’m probably not going to write it, since I’m neck-deep in other projects, but if I had the time, I would. It would need to be a macro of some sort, something to maintain session variables as they go in and out of scope. With maybe even possibly a state chart to show what the user flow looks like to clients and less tech-oriented types. That would definitely help to get a mental snapshot of where things might screw up.

August 1st, 2008

In the time of spirits thoughts grew till they over topped my head, whose offspring they yet were; they hovered about me and convulsed me like fever-phantasies — an awful power. The thoughts had become corporeal on their own account, were ghosts, e. g. God, Emperor, Pope, Fatherland, etc. If I destroy their corporeality, then I take them back into mine, and say: “I alone am corporeal.” And now I take the world as what it is to me, as mine, as my property; I refer all to myself.

– Max Stirner, The Ego and Its Own, p 15.

July 25th, 2008

Freelancing seems to have no sensible pattern to it. It’s very chaotic in nature. Each prospect is another batch of spaghetti thrown at the wall. Sometimes none of it sticks.. and you’re left with nothing for 2-3 weeks. Sometimes it all sticks, and you have 5 clients expecting work done by the end of the day! The ups and downs are crazy, but I’d rather have that than a boring office job any day.

July 22nd, 2008

Is it just me, or do all these new software manifestos seem more like art manifestos then like serious critiques of the industry?

Like Design Driven Development.. Reading the Wikipedia of this philosophy, you get some very dynamic prose, but you’re let down because they’re not really saying anything new..! Just re-contextualizing existing problems. Next time I get the chance, I’ll start telling people I’m a futurist programmer or something.

July 15th, 2008

Ionize now has a home. See if you can break it :)

Messing around with SexpProcessor

July 13th, 2008
              require 'rubygems'
              require 'parse_tree'
              require 'ruby2ruby'
              
              Sexp.class_eval do
                def unbox
                  if length == 1
                    self.first
                  else
                    self
                  end
                end
              end
              
              class Lispify < SexpProcessor
                def initialize
                  super
                  self.auto_shift_type = true
                  self.require_empty   = false
                end
              
                def process_vcall(expr)
                  s(expr.first)
                end
              
                def process_call(expr)
                  expr = Sexp.from_array(expr)
              
                  first  = process(expr[0]).unbox
                  second = process(expr[2]).unbox
              
                  s(expr[1], first, second)
                end
              
                def process_array(expr)
                  process(expr.first)
                end
              end
              
              

Which results in:

              >> equation = %q{ x + x * x - x }
              >> Lispify.new.process(ParseTree.translate(equation))
              => s(:-, s(:+, :x, s(:*, :x, :x)), :x)
              >>
              

So now you’re in perfect shape to perform some kind of symbolic computation on the equation.

July 13th, 2008

I’ve renamed Php::Parser to Ionize. Not as mystical as I would have liked, but it works for now. It’s got a new home at GitHub.

The TODO on Ionize is now:

  • Create a basic demo site to show off it’s current capabilities
  • Get Php::Environment up and running, even if that means I have to use libphp.so to handle top-level functions
  • Replace the translate stuff with ParseTree’s SexpProcessor, which does 95% of what I’m already doing

Emacs find/replace across directories

July 13th, 2008
M-x find-dired [Enter]

(make sure it’s in the right directory) [Enter]

-name '*.rb' [Enter]

% m rb$ [Enter] (or just mark individual ones with ‘m’)

M-x dired-do-query-replace-regexp [Enter]

regexp-to-search-for [Enter]

string-to-replace-with [Enter]

Then don’t forget to save.

Or there’s M-x tags-query-replace if you have TAGS set up. If you use speedbar (I don’t), I think it provides a way to do it with more of a notion of a “project” than just a directory.

Found here

July 9th, 2008

Restaurants with great food seem to prosper no matter what. A restaurant with great food can be expensive, crowded, noisy, dingy, out of the way, and even have bad service, and people will keep coming. It’s true that a restaurant with mediocre food can sometimes attract customers through gimmicks. But that approach is very risky. It’s more straightforward just to make the food good.

Paul Graham’s Restaurant Theory of Business

July 8th, 2008

By my love and hope I beseech you: Do not throw away the hero in your soul! Hold holy your highest hope!

Friedrich Nietzsche

July 7th, 2008

I’ve been using Dhaka to do PHP Parser for most of the project. I started out using RDParser. But I realized how much of a toy it was when I saw how fast Dhaka was by comparison, even though my Dhaka grammar was going to be almost twice as big. However, now that the project is maturing, I’m running into edge-cases where Dhaka isn’t as good of a fit for my purposes as I’d like. Specifically, Dhaka doesn’t support Unicode by default but I suppose this could be handled. Another issue I’ve had was with it’s lack of a splat operation, so you could get back a list of nodes that match instead of just pairs.

These are only minor at the moment, but the Unicode issue will have to be handled before it could be considered ‘production’. I’ll probably be on the lookout for something similar or maybe even add the functionality I need to Dhaka itself.. Who knows.

Worst. Syntax. Ever.

July 6th, 2008

PHP: Strings – Manual

String access and modification by character

Characters within strings may be accessed and modified by specifying the zero-based offset of the desired character after the string using square array brackets, as in $str[42]. Think of a string as an array of characters for this purpose.

Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose. However, this syntax is deprecated as of PHP 6. Use square brackets instead.

Compiling Ruby to Php is a step in the wrong direction

July 6th, 2008

So I managed to find someone who’s doing Ruby to Php compilation. It seems to be in active development. He has a demo available, and although the source is not available, you can glean from the results how he gets method_missing working on Php: implementing message sends through a single top level function. Ultimately, that route ends up being very similar to what one would expect from Ruby to C.

If you want to know what I think, and of course you do, I think his whole philosophy is wrong.. We shouldn’t have to succumb to antiquated technology like Apache just to deploy our web apps. Even when something like Passenger, I think it’s a step in the wrong direction. It’s too easy to ignore the OS when developing. My theory is that, if you’re forced to run your own VPS, just to even deploy Rails, you’re either a) going crawl back to a lesser language and therefore leave us alone or b) actual sit down and learn how Unix works. The whole Heroku thing seems cool until you realize how it coddles you from the realities of the environment. Sometimes software barriers that are created by platforms are useful for separating the wheat from the shaft even when they’re not intentional.

PHP Parser 0.1.9

July 4th, 2008

Transforms a class definition:

This wasn’t all that tricky. var needed to be converted to attr_accessor. $this-> needed to be converted to self., but otherwise, it was a very straight forward transform.

              class ResultSet {
                var $result;
                var $total_rows;
                var $fetched_rows;
              
                function set_result( $res ) {
                  $this->result = $res;
                }
              
                function get_result() {
                  return $this->result;
                }
              
                function set_total_rows( $rows ) {
                  $this->total_rows = $rows;
                }
              
                function get_total_rows() {
                  return $this->total_rows;
                }
              
                function set_fetched_rows( $rows ) {
                  $this->fetched_rows = $rows;
                }
              
                function get_fetched_rows() {
                  return $this->fetched_rows;
                }
              
                function increment_fetched_rows() {
                  $this->fetched_rows = $this->fetched_rows + 1;
                }
              }
              
              
              class ResultSet
                attr_accessor(:result)
                attr_accessor(:total_rows)
                attr_accessor(:fetched_rows)
                def set_result(res)
                  self.result = res
                end
                def get_result
                  return self.result
                end
                def set_total_rows(rows)
                  self.total_rows = rows
                end
                def get_total_rows
                  return self.total_rows
                end
                def set_fetched_rows(rows)
                  self.fetched_rows = rows
                end
                def get_fetched_rows
                  return self.fetched_rows
                end
                def increment_fetched_rows
                  self.fetched_rows = (self.fetched_rows + 1)
                end
              end
              

Transforms a switch case, and error guard

This one was slightly trickier. The global variable $dbtype need to be replaced throughout the AST, which ended up meaning saving a list of globals for the entire duration of the transform :(. I’d like to keep going for straight replacement transforms without keeping track of state, but some of the more complicated ASTs, along with the behavior of the Dhaka parser, kind of require it.

Specifically, the switch-case AST wasn’t all that complicated but it become a bit of a challenge with Dhaka, because there is no splat operator in it’s parser generator grammar, unlike normal BNF. So nodes would end up [:looking, [:like, [:this]] instead of [:looking, :like, :this]. This required a selective flattening operation that only applied to the statement nodes but not it’s children nodes.

Finally, to give myself an extra challenge, I added Php’s error guard, which ended up being equalvalent to Ruby’s rescue nil idiom. I prefer to use the :try idiom nowadays, but rescue nil does look pretty nice.

One flaw that I should point out is that Php’s switch-case semantics are exactly like C/C++, so the case without an statements will “fall through” to a case below it. This is not true of Ruby and will have to be finagled to produce the correct semantics, probably by joining the conditional expressions, separated by a comma.

              function sql_logout($id)
              {
                global $dbtype;
                switch ($dbtype) {
              
                case "MySQL":
                  $dbi=@mysql_close($id);
                  return $dbi;
                  break;;
              
                case "mSQL":
                  $dbi=@msql_close($id);
                  return $dbi;
                  break;;
              
                case "postgres":
                case "postgres_local":
                  $dbi=@pg_close($id);
                  return $dbi;
                  break;;
              
                case "ODBC":
                case "ODBC_Adabas":
                  $dbi=@odbc_close($id);
                  return $dbi;
                  break;;
              
                case "Interbase":
                  $dbi=@ibase_close($id);
                  return $dbi;
                  break;;
              
                case "Sybase":
                  $dbi=@sybase_close($id);
                  return $dbi;
                  break;;
              
                default:
                  break;;
                }
              }
              
              def sql_logout(id)
                $dbtype
                case $dbtype
                when "MySQL" then
                  dbi = mysql_close(id) rescue nil
                  return dbi
                  break
                when "mSQL" then
                  dbi = msql_close(id) rescue nil
                  return dbi
                  break
                when "postgres" then
                  # do nothing
                when "postgres_local" then
                  dbi = pg_close(id) rescue nil
                  return dbi
                  break
                when "ODBC" then
                  # do nothing
                when "ODBC_Adabas" then
                  dbi = odbc_close(id) rescue nil
                  return dbi
                  break
                when "Interbase" then
                  dbi = ibase_close(id) rescue nil
                  return dbi
                  break
                when "Sybase" then
                  dbi = sybase_close(id) rescue nil
                  return dbi
                  break
                else
                  break
                end
              end
              

PHP Parser 0.1.6

July 1st, 2008
  • Foreach now transforms to an each loop
  • Array lookup
  • Single statement function
  • If-else with nested if
June 30th, 2008

I hate working for stupid companies. Most companies I’ve worked for aren’t really stupid, just ignorant of software.. Which is fine, because most people aren’t really supposed to know much about software. But a stupid company will make you do everything by hand, when automation is the most valuable aspect of software. They’ll make you conform to stupid standards because ‘they said so’, and not because it was a part of an over-arching philosophy. In general, stupid companies just flat-out make you less productive. Some companies don’t do this. Some of them make you more productive. But what’s even worse is when those anti-productive habits that they’ve ingrained upon you start spilling over into your solo projects. That’s the worst aspect about working for a stupid company.

June 28th, 2008

I’m giving this macros in Ruby thing some serious thought.. As it turns out, the def_macro gem isn’t really all that complete and was just an experiment. There’s a slightly better possibility that I might use Raganwald’s rewrite.. But not 100% sure on that either. I might even come up with some kind of interface so end users can rewrite things like PHP’s for loops on their own, but with a decent default config.. Common cases, such as for ($i=0;$i<6;$i++) { ... } could get recognized as just iteration.. Hmm.. but that could get a bit complicated.. Like I said, it requires some thought, but it’s definitely a piece of this puzzle.

June 28th, 2008

And Eliezer Yudkowsky merely confirms what we were all thinking

So you came here. Maybe you don’t understand what the equation says. Maybe you understand it in theory, but every time you try to apply it in practice you get mixed up trying to remember the difference between p(a|x) and p(x|a), and whether p(a)*p(x|a) belongs in the numerator or the denominator. Maybe you see the theorem, and you understand the theorem, and you can use the theorem, but you can’t understand why your friends and/or research colleagues seem to think it’s the secret of the universe. Maybe your friends are all wearing Bayes’ Theorem T-shirts, and you’re feeling left out. Maybe you’re a girl looking for a boyfriend, but the boy you’re interested in refuses to date anyone who “isn’t Bayesian”. What matters is that Bayes is cool, and if you don’t know Bayes, you aren’t cool.

Well.. he asked for it...