Page 1 of 3 123 LastLast
Results 1 to 10 of 24

Thread: Code I wrote whilst angry

  1. #1
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,878
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default Code I wrote whilst angry

    I just used this code to vent some frustration earlier, hope you all like it. It's pretty self-explanatory. It's probably too theoretical to go into the DD scripts archives, so I'll just leave it lying about here.
    Code:
    var Generic = (function() {
      var MATCH_FAIL = {},
          MATCH_ANY  = function() { return MATCH_ANY; };
    
      function create(fallback) {
        var s = function() {
          for (var i = 0, args = Array.prototype.slice.call(arguments), r; i < specs.length; ++i)
            if ((r = specs[i].match(args)) !== MATCH_FAIL)
              return r;
    
          if (s._fallback)
            return s._fallback.apply(this, args);
    
          throw new Error("Generic: No methods matched and no fallback provided.");
        }, specs = s._specs = [];
    
        s.specialise = specialise;
        s.addFallback = addFallback;
        if (fallback)
          s.addFallback(fallback);
    
        return s;
      }
    
      function specialise(patterns, func) {
        var s = this._specs;
    
        s[s.length] = new Specialisation(patterns, func, this);
    
        return this;
      }
    
      function addFallback(func) {
        this._fallback = func;
    
        return this;
      }
    
      /**** Begin Specialisation ****/
    
      function Specialisation(patterns, func, context) {
        this.patterns = patterns;
        this.func = func;
        this.context = context;
      }
    
      Specialisation.compatible = function(value, pattern) {
        if (pattern === MATCH_ANY && value !== undefined)
          return true;
        else if ((typeof pattern === "string" || pattern instanceof String) && typeof value === pattern)
          return true;
        else if (typeof pattern === "function" && value instanceof pattern)
          return true;
        else if (pattern instanceof Pattern)
          return pattern.guard(value);
        else if (pattern instanceof Interface)
          return pattern.match(value);
    
        return false;
      };
    
      Specialisation.prototype = {
        match: function(args) {
          for (var i = 0, a = this.patterns, n = a.length; i < n; ++i)
            if (!Specialisation.compatible(args[i], a[i]))
              return MATCH_FAIL;
    
          return this.func.apply(this.context, args);
        }
      };
    
      /**** Begin Pattern ****/
    
      function Pattern(guard) {
        this.guard = guard;
      }
    
      function GUARD(func) {
        return new Pattern(func);
      }
    
      function GUARD_IS(right) {
        return new Pattern(function(val) {
          return val === right;
        });
      }
    
      /**** Begin Interface ****/
    
      function Interface(obj) {
        if (!(this instanceof Interface))
          return new Interface(obj);
    
        for (var x in obj)
          if (obj.hasOwnProperty(x))
            this[x] = obj[x];
      }
    
      Interface.getSkeleton = function(obj) {
        var r = {};
    
        for (var x in obj)
          if (obj.hasOwnProperty(x))
            r[x] = typeof obj[x];
    
        return new Interface(r);
      };
    
      Interface.prototype = {
        match: function(value) {
          for (var x in this)
            if (this.hasOwnProperty(x) && !Specialisation.compatible(value[x], this[x]))
              return false;
    
          return true;
        }
      };
    
      return {
        create: create,
        Interface: Interface,
        GUARD: GUARD,
        GUARD_IS: GUARD_IS,
        MATCH_ANY: MATCH_ANY
      };
    })();
    
    function Animal(species) {
      this.species = species;
    }
    
    var iAnimal = Generic.Interface.getSkeleton(new Animal("foo"));
    
    var iDog = Generic.Interface({'species' : Generic.GUARD_IS("dog")});
    
    var sound = Generic.create()
      .specialise([iDog, 'undefined'], function() {
        print("I got a dog!  I got one!");
      })
      .specialise(['string', iAnimal], function(snd, an) {
        print("A " + an.species + " says '" + snd + "',");
      })
      .specialise([iAnimal, 'string'], function(an, snd) {
        print("but a " + an.species + " says '" + snd + "',");
      })
      .specialise([Animal], function(an) {
        print("and a " + an.species + " is apparently silent.");
      })
      .specialise([Generic.MATCH_ANY, 'undefined'], function(val) {
        print("... and whatever noise a " + val + " makes...");
      })
      .addFallback(function() {
        print("Er... random animal noise?");
      });
    
    sound(new Animal("dog"));
    sound("woof", new Animal("dog"));
    sound(new Animal("cat"), "miaow");
    sound(new Animal("frog"));
    sound(42);
    sound(4, 5);
    Last edited by Twey; 08-10-2008 at 12:08 PM.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends franšais | entiendo espa˝ol | t˘i Ýt hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  2. #2
    Join Date
    Jan 2006
    Location
    Ft. Smith, AR
    Posts
    795
    Thanks
    57
    Thanked 130 Times in 117 Posts

    Default

    and a cow says: MOO...
    --------------------------------------------------
    Reviews, Interviews, Tutorials, and STUFF
    --------------------------------------------------
    Home of the SexyBookmarks WordPress plugin

  3. #3
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,878
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    Only if you specialise to it.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends franšais | entiendo espa˝ol | t˘i Ýt hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  4. #4
    Join Date
    Jul 2006
    Location
    Canada
    Posts
    2,581
    Thanks
    13
    Thanked 28 Times in 28 Posts

    Default

    Uh I tested it, and all that happened was it printed a blank page.
    - Mike

  5. #5
    Join Date
    Jan 2006
    Location
    Ft. Smith, AR
    Posts
    795
    Thanks
    57
    Thanked 130 Times in 117 Posts

    Default

    sound("MOO", new Animal("cow"));
    --------------------------------------------------
    Reviews, Interviews, Tutorials, and STUFF
    --------------------------------------------------
    Home of the SexyBookmarks WordPress plugin

  6. #6
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,878
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    The print() statements I used are meant for running in a console, change them to alert() or something if you intend to run it in a browser.

    What it does isn't remarkable, that's just standardly-idiotic sample code. What's hopefully interesting is how it does it.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends franšais | entiendo espa˝ol | t˘i Ýt hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  7. #7
    Join Date
    Jul 2006
    Location
    Canada
    Posts
    2,581
    Thanks
    13
    Thanked 28 Times in 28 Posts

    Default

    Yeah I'm not entirely sure what it does. It just looks like the Generic method creates functions?
    - Mike

  8. #8
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,878
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    No, it's a crude implementation of dispatching to functions based on argument types — one way of doing classical OO in a purely-functional language. It can be thought of in terms of Haskell's typeclasses, or Common Lisp's... well, generics; that latter was the inspiration for this.

    Simply, a single generic is created, and then onto that generic can be attached various specialisations to various argument types. When the generic is called, unlike a traditional function, it inspects its arguments and dispatches the call and the arguments to the appropriate specialisation. My implementation here caters to Javascript's split personality with regards to OO by allowing dispatching using both duck-typing via interfaces, and by type or instance as reported by typeof and instanceof.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends franšais | entiendo espa˝ol | t˘i Ýt hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  9. #9
    Join Date
    Jul 2006
    Location
    Canada
    Posts
    2,581
    Thanks
    13
    Thanked 28 Times in 28 Posts

    Default

    Ah I see... I think I understand it. A little bit, at least.
    - Mike

  10. #10
    Join Date
    May 2007
    Location
    USA
    Posts
    373
    Thanks
    2
    Thanked 4 Times in 4 Posts

    Default

    Code:
    typeof pattern === "function" || pattern instanceof Function
    I tested on IE and FF and you don't need the latter half for functions.

    "Structure and Interpretation of Computer Programs" (large PDF link) talks about this type of dispatch if anyone is curious. (Begins talking about it on 2.4)
    Last edited by Trinithis; 08-09-2008 at 10:32 PM.
    Trinithis

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •