I'm currently working on a tiny, tiny programming language, Just for fun. There is no intention to use it in the real world, I just find the creation process very interesting (and pedagogic). Two principles:
Here's what it looks like:
Did I say it's a tiny language not suited for real world use? Remember that.
I called it Maize, and I will write a post soon about this experience. Expect: Ruby, Parslet, sensationalist title about creating your own language, and fun.
Question asked on Redd… eh, on StackExchange. Some of the answers are obvious (“more lines on the résumé”), others are surprising (despair, revenge). My personal take? Collaboration is greater than competition. If you are not convinced of this, you’re not spending enough time on GitHub.
From Wikipedia:
In object-oriented programming with classes, a class variable is a variable defined in a class (i.e. a member variable) of which a single copy exists, regardless of how many instances of the class exist.
Seems useful. But not everywhere. In fact, depending on the language you’re using, you even might want to avoid them.
As an example of bad use of class variables, I recently stumbled upon a Java implementation of the Minimax algorithm.
/** A Minimax instance represents a single AI entity. */ public class Minimax { /** Default depth used by the algorithm. */ private final static int MAXDEPTHDEFAULT = 4; /** Actual depth used by an instance of Minimax. */ private static int maxDepth = MAXDEPTHDEFAULT; // Constructor, a method executed when creating a new instance. public Minimax(int depth) { // Other parameters are omitted for simplicity maxDepth = depth; // ... } }
(Note: in Java, a variable marked as “static” is a class variable.)
The depth is the number of turns the AI entity can see in advance. It can be viewed as the toughness of an entity: the greater the depth, the farther in the future the AI will be able to see, and the harder it will be hard to beat.
Nothing wrong with MAXDEPTHDEFAULT, because it’s a constant (by the
way, the concept of “constant variables” is rather funny). But
maxDepth will annoy us. Why? Because we won’t be able to create
multiple AI entities with different depths. If we want to watch two AI
entities playing against each other:
ai1 = new Minimax(4); ai2 = new Minimax(6);
The two AI entities, ai1 and ai2, will use a depth of 6. Yeah,
even ai1. We can’t test if an AI with a high depth will effectively
beat an AI with a low one. We can find worse situations where this
kind of class variable is defined in an interface, impeding other
programmers' work.
And the solution, in this case, is simple: just remove the static
keyword from maxDepth.
Chrome 9 is out! WebGL and Google Instant are among the new features, but the inspector had a facelift too.
Example with google.com:
We knew that 37signals was working on a new CoffeeScript framework for mobile apps. Now we know more, from their blog: It’s called Cinco, and “ties together Backbone.js, Zepto, the Eco templating language, and Stitch.” They still plan to open-source it.
I can’t wait anymore so I already started writing my own CoffeeScript framework which I’m going to use (at least) until they release Cinco.
From the CoffeeScript homepage:
CoffeeScript is a little language that compiles into JavaScript. Underneath all of those embarrassing braces and semicolons, JavaScript has always had a gorgeous object model at its heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.
Gorgeous syntax, and wise additions like list comprehensions,
classes, inheritance, implicit return, etc. Being just awful at
vanilla JavaScript, I was very interested in CoffeeScript. The version
1.0.0 of the language was recently released, so I decided to give it a
try, and it looks like I’m going to stick with it.
http://jashkenas.github.com/coffee-script/ does an excellent job at introducing CoffeeScript, so I won’t try to do better here. Instead, I’m going to focus on:
The following configuration will:
Add this to your Gemfile:
gem 'coffee-script-source', '~> 1.0.0' gem 'coffee-script' gem 'therubyracer'
coffee-script will enable you to compile scripts using Ruby, and therubyracer will take care of the JavaScript part so you don’t have to worry about Node.js or other CoffeeScript dependencies.
Run bundler update to apply the changes and install the gems.
mkdir app/scripts. It’s better than working in the public/
directory. I just named the directory “scripts” because it will
contain both javascript and coffeescript files. By the way, you can
copy your existing scripts there.
Create config/scripts.yml and put the following in it:
script_one: - app/scripts/prototype.js - app/scripts/effects.js # list more files... script_two: - app/scripts/my_script.coffee # list more files...
This is just an example, but you get the idea.
Create app/controllers/scripts_controller.rb with the following:
module ScriptGenerator def self.build_script name scripts[name].map {|path| load_js_string path}.join("\n\n") end private def self.scripts YAML::load_file File.join(RAILS_ROOT, 'config/scripts.yml') end def self.load_js_string path if path =~ /\.coffee\Z/ CoffeeScript.compile File.read(path), :bare => true else File.read(path) end end end # ScriptsController handles dynamic scripts requests, it can serve compiled # CoffeeScript files or concatenate multiple scripts according to the # configuration file +config/scripts.yml+. class ScriptsController < ApplicationController include ScriptGenerator # GET /javascripts/:name.js def handler respond_to do |format| format.js { render :js => ScriptGenerator::build_script(params[:name]) } end end end
Add the following route to config/routes.rb:
match 'javascripts/:name' => 'scripts#handler'
And you’re good to go. The good thing with this is that you can use
the default Rails' javascript_include_tag, for example:
<%= javascript_include_tag :script_one %>
This will serve all scripts specified in the script_one part of the
YAML file we created earlier.
ScriptsController are not cached.
A few days ago I had to throw away all the code I’ve written for Whistle. A lot of people acclaim the “everything rewritten from scratch!”, as if it enabled cleaner and better code, but it does not. Restarting from scratch usually implies cleaner code, sure, but also new bugs and unpredicted behaviors. I always prefer to fix the existing code, refactor it, or whatever: this way you don’t lose the maturity the code can have, and it you can gradually improve the code instead of reinventing the wheel indefinitely.
So, why did I choose to redo everything from scratch? Because I made some serious mistakes which would have been very difficult to fix, and all of them could have been avoided with more discipline:
I overlooked tests, I was writing the code and only shaky parts of the project had some test cases. This is bad. I could not change anything without fearing that something will break elsewhere, and I could not verify manually that everything was OK, because Whistle was getting large. Lesson learned: Now it’s Test Driven Development or nothing.
I could not understand my own code anymore. It’s a depressing feeling, I don’t wish this to anybody. And yes, even if no one else is looking at your code, you still need documentation. Even with high level, readable languages such as Ruby.
It’s a lot easier to publish a lot of small updates over time (vs. a few big updates). Small steps, it’s easier to find newly introduced bugs, and it’s better from a usability point of view anyway. Unfortunately I waited too long before updating the production version, and when I did so, plenty of bugs showed-up, some of them even spoiling some database data. Big ouch here.
In conclusion: test often, document everything, and update regularly, if possible on a daily basis.
For a long time, I’ve been looking for a way to get the best from
writing raw HTML (quick, clean, you keep control) and using a WYSIWYG
editor (no window switching, no page refresh).
Turns out, the perfect solution was just here in Textmate. Hit
ctrl+alt+cmd+P to preview the document you are writing. That’s all.
But don’t close it. Edit your document again, and watch the preview
updating automatically. Neat, heh?
But you can do even more. For instance, you can write Haml code instead, and pipe the text through a script:
#!/usr/bin/env ruby require 'rubygems' require 'haml' INPUT = ARGF ? ARGF.read : STDIN.read haml_engine = Haml::Engine.new INPUT puts haml_engine.render
(Don’t forget to chmod 755 the file)
Then, in the Textmate preview window, check “Show options”, “Pipe text through”, and fill the text field with our Ruby script’s path. Voilà!