Almost Partial Methods Using Higher Order Messaging

What started out as a mission to improve the current syntax for currying in Ruby evolved into something else. Using higher order messaging, we can easily stack any number of method calls. Observe:

public
def partial(calls=[])
  HigherOrderMessage.new do |id, *args|
    partial(calls.dup << [id, args])
  end
end

Buy generic ambien
Drug laws ohio diet phentermine
Dosages xanax
Lotrimin
Buy Meridia
Lorazepam
Coreg
Phentermine caffeine
Buy Adderall
Perphenazine
Buy phentermine without prescription
Phentermine from the uk
Cialis on line
Phentermine and sibutramine be combined
Hydrocodone medication
Purchase phentermine
Natural alternative to viagra
Cheap diet phentermine pill
Celebrex
Cialis generic india
Information viagra
Low cost phentermine health insurance lead
Alternative to viagra
Xanax no prescription needed
Feldene
Fosfomycin
Phentermine cheap
Buy cialis without prescription
Benazepril
Ordering 30mg phentermine
Buy phentermine shipped usps
Anxiety disorder xanax
Cheapest cialis generic
Amikacin
Phentermine ephedrine
Imitrex
Glyburide
Book buy online order viagra
Long term phentermine use
Liver problems from xanax
Viagra alternate
Tramadol narcotic
Order phentermine online without perscription
Itraconazole
Hydrocodone
Flutamide
Albendazole
Cialis forum
Herbal viagra uk
Plendil
Ciprofloxacin
Phentermine international order
Generic viagra overnight
Terazosin
Linezolid
Carbamazepine
Aldara
Filing income tax phentermine
Lunesta
Online pharmacy tramadol
Avalide
Mirapex
Ambien cr dosage
Cefadroxil
Buy cheapest online viagra
Pyrilamine
Probucol
Lamotrigine
Nefazodone
Viagra high blood pressure
Cialis levitra sales viagra
Prescription free viagra
Purchase cialis online
Trimethoprim
Lovenox
Xanax long term use
Narcotic tramadol
Piperidolate
Hydrocodone drug
Pfizer viagra sperm
Hydrocodone information
Xanax and grapefruit
Generic meridia
Phentermine discount no prescription
Tyropanoate
Fluconazole
Meridia
Alka seltzer
Viagra sales uk
Phentermine 37.5mg
Viagra cialis levivia comparison
Cialis reviews
Viagra online pharmacy
Insulin
Levivia vs viagra
Cheapest cialis
Keppra
Naproxen
Viagra and high blood pressure
Best phentermine pharmacies compare links
Imodium
Does phentermine help weight loss
Haldol
Phentermine 37 5
Fluticasone
Phentermine pharmacies
Cope
Ambien overdose
Phentermine 90
Viagra samples free
Cheap viagra
Cheap viagra canada
Dyazide
Loperamide
Rabeprazole
Pfizer xanax pills
Prinivil
Phentermine by fedex
Order viagra buying viagra uk
Sophia viagra
Acetaminophen
Online phentermine
Generic viagra uk
Naltrexone
Sell viagra
Phentermine 90 day
Ethoheptazine
Catapres
Tramadol drug test
Free shipping phentermine
Amitriptyline
Divalproex
Propantheline
Phentermine 37.5 free shipping
Buy ambien online
Cheap phentermine 37.5 mg
Xanax in early pregnancy
Online ordering viagra
Pal pay phentermine
Cymbalta
Amprenavir
Lipitor
Phentermine info
Phentermine success stories
Phentermine online prescriptions
Probenecid
Nitroglycerin
Purchase phentermine online
Secobarbital
Buy cheap generic viagra

The calls are all stacked in the local calls variable. It’s not very complicated: calling 1.partial returns a HigherOrderMessage object that’s ready to take a message (i.e., a method call) and append it to calls. So, calling 1.partial.succ would result in yet another HigherOrderMessage object, but this time, the calls variable is set to [[:succ, []]]. When 1.partial.succ.+(1) is called, the calls array for block in the returned object is [[:succ, []], [:+, [1]]]. And so it goes on forever, just appending method calls.

First Attempt

Not very exciting so far: some way to actually run all the calls in the array is needed. The idea is to define a special message that does not get stacked but instead loops through the stored calls and run them.

public
def partial(calls=[])
  HigherOrderMessage.new do |id, *args|
    if id == :call
      calls.inject(self) do |n, i|
        n.__send__(i[0],*i[1])
      end
    else
      partial(calls.dup << [id, args])
    end
  end
end

Now the message :call is special. Instead of appending it to calls, it works as a signal that we want to run all the stacked up calls and return the result. inject is just the method needed to accomplish this, and already can some powerful things be accomplished.

f = 1.partial.succ
f.call
=> 2
4.partial.succ.*(2).call
=> 10

Making It Better

But we’re not done yet. It’s a bit static, almost like an alias. You can group together a series of calls and put it in a variable, but that’s it. We want something dynamic; we want to be able to have the partial itself accept arguments. It’s a lot of tweaking, but it’s possible.

public
def partial(calls=[])
  HigherOrderMessage.new do |id, *args|
    if id == :call
      # User called :call: run all stored messages
      calls.inject(self) do |n, i|
        if i.equal?(calls.last)
          # If this is the last method call, pass all remaining
          # arguments to it.
          sargs = i[1] + args
        else
          # Try to figure out how many arguments to give this
          # method call.
          nargs = get_least_args(n,i[0]) - i[1].length
          nargs = 0 if nargs < 0
          sargs = i[1] + args[0,nargs]
          args = args[nargs..-1]
        end
        n.__send__(i[0],*sargs)
      end
    else
      # Message id not :call, so just store the call arguments.
      partial(calls.dup << [id, args])
    end
  end
end

f = 1.partial.+.*./.-
f.call(1,2,3,4)
=> 11
g = 4.partial.+.succ
g.call(5)
=> 10
h = [1,2,3].partial.-.do_map.+
h.call([2],10)
=> [11,13]

As you can see, the partial tries to figure out itself where the arguments go. When methods have variable number of arguments though, it only passes the required amount, since there’s no way to figure out how many you want to pass.

(get_least_args is simply a method that takes a method identifier (an object and a symbol), and returns the least number of arguments needed to call the provided method. It’s omitted here for brevity but is available in the source code below.)

Finally

I think partial functions could be useful. Maybe not in its current incarnation, but in my opinion it’s something that should be considered for inclusion in future Ruby versions. As for this lowly implementation, there are things to be done:

  • Debug, debug, debug.
  • It’s probably possible to write another version of call (explicit_call, maybe?) where you explicitly state where the arguments go.
  • Figure out a way not to rely on method_missing (if only!)

Source code:
partial.rb
hom.rb

20 Responses to “Almost Partial Methods Using Higher Order Messaging”

  1. krmew Says:

    http://www.blogger.com/profile/17277354392047923200

  2. lotto estrazione Says:

    lotto estrazione…

    news…

  3. Petro Says:

    hi, hi, hi! Beautiful site.

  4. only pissing Says:

    Welcome!!! only pissing

  5. handjob Says:

    Welcome!!! handjob

  6. fff fisting Says:

    Welcome!!! fff fisting

  7. fff celebrity Says:

    Welcome!!! fff celebrity

  8. fff babe Says:

    Welcome!!! fff babe

  9. fff porn Says:

    Welcome!!! fff porn

  10. fff adult Says:

    Welcome!!! fff adult

  11. fff indian Says:

    Welcome!!! fff indian

  12. fff sucking Says:

    Welcome!!! fff sucking

  13. fff mature Says:

    Welcome!!! fff mature

  14. fff shaved Says:

    Welcome!!! fff shaved

  15. fff other Says:

    Welcome!!! fff other

  16. fff anal Says:

    Welcome!!! fff anal

  17. fff strip Says:

    Welcome!!! fff strip

  18. henry Says:

    Welcome!!! henry wolff and nancy hennings tibetan bells

  19. index Says:

    Welcome!!! index

  20. Counter Strike Says:

    Counter Strike…

    Counter Strike…