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
March 2nd, 2007 at 23:28
http://www.blogger.com/profile/17277354392047923200
April 30th, 2007 at 11:13
lotto estrazione…
news…
July 9th, 2007 at 08:35
hi, hi, hi! Beautiful site.
July 16th, 2007 at 07:02
Welcome!!! only pissing
July 19th, 2007 at 20:41
Welcome!!! handjob
August 4th, 2007 at 02:20
Welcome!!! fff fisting
August 4th, 2007 at 03:45
Welcome!!! fff celebrity
August 4th, 2007 at 05:15
Welcome!!! fff babe
August 4th, 2007 at 06:41
Welcome!!! fff porn
August 6th, 2007 at 16:34
Welcome!!! fff adult
August 6th, 2007 at 18:14
Welcome!!! fff indian
August 6th, 2007 at 21:33
Welcome!!! fff sucking
August 6th, 2007 at 23:27
Welcome!!! fff mature
August 7th, 2007 at 01:15
Welcome!!! fff shaved
August 7th, 2007 at 03:14
Welcome!!! fff other
August 7th, 2007 at 06:26
Welcome!!! fff anal
August 7th, 2007 at 10:33
Welcome!!! fff strip
August 8th, 2007 at 22:37
Welcome!!! henry wolff and nancy hennings tibetan bells
August 9th, 2007 at 00:21
Welcome!!! index
September 2nd, 2007 at 14:35
Counter Strike…
Counter Strike…