example - python lambda aws
¿Por qué son útiles las lambdas de Python? (26)
Estoy tratando de averiguar lambda de Python. ¿Es la lambda uno de esos ítems del lenguaje "interesante" que en la vida real deberían olvidarse?
Estoy seguro de que hay algunos casos de vanguardia en los que podría ser necesario, pero dada la oscuridad de la misma, la posibilidad de que se redefina en futuras versiones (mi suposición basada en las distintas definiciones de la misma) y la claridad de codificación reducida, en caso ser evitado?
Esto me recuerda al desbordamiento (desbordamiento del búfer) de los tipos C: apuntando a la variable superior y la sobrecarga para establecer los otros valores de campo. Se siente como una especie de maestría en tecnología, pero una pesadilla de programador de mantenimiento.
Acabo de empezar a Python y corrí de cabeza a Lambda, lo que me llevó un tiempo descifrarlo.
Tenga en cuenta que esto no es una condena de nada. Todo el mundo tiene un conjunto diferente de cosas que no vienen fácilmente.
¿Es la lambda uno de esos ítems del lenguaje ''interesantes'' que en la vida real deberían olvidarse?
No.
Estoy seguro de que hay algunos casos extremos en los que podría ser necesario, pero dada la oscuridad de la misma,
No es oscuro. Los últimos 2 equipos en los que he trabajado, todos usaron esta función todo el tiempo.
la posibilidad de que se redefina en futuras versiones (mi suposición se basa en las distintas definiciones de la misma)
No he visto propuestas serias para redefinirlo en Python, más allá de arreglar la semántica de cierre hace unos años.
y la claridad de codificación reducida, ¿debería evitarse?
No está menos claro, si lo estás usando bien. Por el contrario, tener más construcciones de lenguaje disponibles aumenta la claridad.
Esto me recuerda al desbordamiento (desbordamiento del búfer) de los tipos C: apuntar a la variable superior y sobrecargar para establecer los otros valores de campo ... una especie de maestría tecnológica pero una pesadilla de mantenimiento del programador
Lambda es como desbordamiento de búfer? Guau. No puedo imaginarme cómo usas lambda si crees que es una "pesadilla de mantenimiento".
¿Estás hablando de funciones lambda ? Me gusta
lambda x: x**2 + 2*x - 5
Esas cosas son bastante útiles. Python admite un estilo de programación llamado programación funcional en el que puedes pasar funciones a otras funciones para hacer cosas. Ejemplo:
mult3 = filter(lambda x: x % 3 == 0, [1, 2, 3, 4, 5, 6, 7, 8, 9])
establece mult3
a [3, 6, 9]
, aquellos elementos de la lista original que son múltiplos de 3. Esto es más corto (y, uno podría argumentar, más claro) que
def filterfunc(x):
return x % 3 == 0
mult3 = filter(filterfunc, [1, 2, 3, 4, 5, 6, 7, 8, 9])
Por supuesto, en este caso particular, podría hacer lo mismo que una lista de comprensión:
mult3 = [x for x in [1, 2, 3, 4, 5, 6, 7, 8, 9] if x % 3 == 0]
(o incluso como range(3,10,3)
), pero hay muchos otros casos de uso más sofisticados en los que no se puede usar una lista de comprensión y una función lambda puede ser la forma más corta de escribir algo.
Devolviendo una función desde otra función
>>> def transform(n): ... return lambda x: x + n ... >>> f = transform(3) >>> f(4) 7
Esto se usa a menudo para crear envolturas de funciones, como los decoradores de Python.
Combinando elementos de una secuencia iterable con
reduce()
>>> reduce(lambda a, b: ''{}, {}''.format(a, b), [1, 2, 3, 4, 5, 6, 7, 8, 9]) ''1, 2, 3, 4, 5, 6, 7, 8, 9''
Ordenar por una clave alternativa
>>> sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x)) [5, 4, 6, 3, 7, 2, 8, 1, 9]
Yo uso las funciones lambda sobre una base regular. Me tomó un tiempo acostumbrarme a ellos, pero finalmente llegué a entender que son una parte muy valiosa del idioma.
Casi cualquier cosa que pueda hacer con lambda
se puede hacer mejor con funciones nombradas o con expresiones de lista y generador.
Por lo tanto, en su mayor parte, solo debería ser uno de esos en cualquier situación (excepto tal vez para el código escrito en el intérprete interactivo).
Como se indicó anteriormente, el operador lambda en Python define una función anónima, y en Python las funciones son cierres. Es importante no confundir el concepto de cierres con el operador lambda, que es simplemente una metadona sintáctica para ellos.
Cuando empecé en Python hace unos años, usé mucho las lambdas, pensando que eran geniales, junto con las listas de comprensión. Sin embargo, escribí y tengo que mantener un gran sitio web escrito en Python, con el orden de varios miles de puntos de función. Aprendí por experiencia que las lambdas podrían estar bien para hacer prototipos de cosas, pero no ofrecen nada sobre las funciones en línea (cierres con nombre), excepto para guardar algunas claves, o algunas veces no.
Básicamente esto se reduce a varios puntos:
- es más fácil leer software que está escrito explícitamente usando nombres significativos. Los cierres anónimos, por definición, no pueden tener un nombre significativo, ya que no tienen nombre. Esta brevedad parece, por alguna razón, también infectar los parámetros lambda, por lo que a menudo vemos ejemplos como lambda x: x + 1
- es más fácil reutilizar los cierres con nombre, ya que se puede hacer referencia a ellos más de una vez, cuando hay un nombre para referirse a ellos.
- es más fácil depurar el código que utiliza cierres con nombre en lugar de lambdas, porque el nombre aparecerá en las trazas y en torno al error.
Esa es razón suficiente para redondearlos y convertirlos en cierres con nombre. Sin embargo, tengo otros dos rencores contra los cierres anónimos.
El primer rencor es simplemente que son solo otra palabra clave innecesaria que abarrota el lenguaje.
El segundo rencor es más profundo y en el nivel de paradigma, es decir, no me gusta que promuevan un estilo de programación funcional, porque ese estilo es menos flexible que el paso de mensajes, orientado a objetos o estilos de procedimiento, porque el cálculo lambda no es Turing- completa (afortunadamente en Python, todavía podemos romper esa restricción incluso dentro de un lambda). Las razones por las que siento que las lambdas promueven este estilo son:
Hay un retorno implícito, es decir, parece que "deberían" ser funciones.
Son un mecanismo alternativo de ocultación del estado a otro mecanismo más explícito, más legible, más reutilizable y más general: los métodos.
Me esfuerzo mucho por escribir Python sin lambda y eliminar las lambdas a la vista. Creo que Python sería un lenguaje un poco mejor sin lambdas, pero esa es solo mi opinión.
Dudo que lambda se vaya. Ver la publicación de Guido sobre finalmente renunciar a intentar eliminarlo. También vea un resumen del conflicto .
Puede consultar esta publicación para obtener más de un historial sobre el acuerdo detrás de las características funcionales de Python: http://python-history.blogspot.com/2009/04/origins-of-pythons-functional-features.html
Curiosamente, el mapa, el filtro y las funciones de reducción que originalmente motivaron la introducción de lambda y otras características funcionales han sido reemplazados en gran medida por las comprensiones de listas y las expresiones generadoras. De hecho, la función de reducción se eliminó de la lista de funciones incorporadas en Python 3.0. (Sin embargo, no es necesario enviar quejas sobre la eliminación de lambda, el mapa o el filtro: se están quedando. :-)
Mis propios dos centavos: Rara vez la lambda vale la pena en lo que a claridad se refiere. Generalmente hay una solución más clara que no incluye lambda.
El resumen de dos líneas:
- Closures : Muy útiles. Apréndelos, úsalos, ámalos.
-
lambda
clavelambda
de Python: innecesaria, ocasionalmente útil. Si se encuentra haciendo algo remotamente complejo con él, guárdelo y defina una función real.
En Python, lambda
es solo una forma de definir funciones en línea,
a = lambda x: x + 1
print a(1)
y..
def a(x): return x + 1
print a(1)
..es exactamente igual.
No hay nada que pueda hacer con lambda que no pueda hacer con una función normal; en Python, las funciones son un objeto como cualquier otra cosa, y lambdas simplemente define una función:
>>> a = lambda x: x + 1
>>> type(a)
<type ''function''>
Sinceramente, creo que la palabra clave lambda
es redundante en Python: nunca he tenido la necesidad de usarlas (o he visto una que se usa cuando una función normal, una lista de comprensión o una de las muchas funciones integradas podrían haberse utilizado mejor en su lugar)
Para un ejemplo completamente aleatorio, del artículo "¡La lambda de Python está rota!" :
Para ver cómo se rompe lambda, intente generar una lista de funciones
fs=[f0,...,f9]
dondefi(n)=i+n
. Primer intento:
>>> fs = [(lambda n: i + n) for i in range(10)] >>> fs[3](4) 13
Yo diría que, incluso si eso funcionara, es horrible y "no hippónico", la misma funcionalidad podría escribirse de muchas otras formas, por ejemplo:
>>> n = 4
>>> [i + n for i in range(10)]
[4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
Sí, no es lo mismo, pero nunca he visto una causa en la que se haya requerido generar un grupo de funciones lambda en una lista. Podría tener sentido en otros idiomas, pero Python no es Haskell (o Lisp, o ...)
Tenga en cuenta que podemos usar lambda y aún así lograr los resultados deseados de esta manera:
>>> fs = [(lambda n,i=i: i + n) for i in range(10)] >>> fs[3](4) 7
Editar:
Hay algunos casos donde lambda es útil, por ejemplo, a menudo es conveniente cuando se conectan señales en aplicaciones PyQt, como esto:
w = PyQt4.QtGui.QLineEdit()
w.textChanged.connect(lambda event: dothing())
Solo hacer w.textChanged.connect(dothing)
llamaría al método dothing
con un argumento de event
adicional y causaría un error. El uso de la lambda significa que podemos descartar ordenadamente el argumento sin tener que definir una función de ajuste.
Encuentro que lambda es útil para una lista de funciones que hacen lo mismo, pero para diferentes circunstancias. Como las reglas del plural de Mozilla .
plural_rules = [
lambda n: ''all'',
lambda n: ''singular'' if n == 1 else ''plural'',
lambda n: ''singular'' if 0 <= n <= 1 else ''plural'',
...
]
# Call plural rule #1 with argument 4 to find out which sentence form to use.
plural_rule[1](4) # returns ''plural''
Si tuvieras que definir una función para todos aquellos a los que te volverías loco al final de la misma. Además, no estaría bien con nombres de funciones como plural_rule_1
, plural_rule_2
, etc. Y necesitarías eval()
cuando plural_rule_2
de una función variable id.
He estado usando Python durante algunos años y nunca he encontrado un caso en el que haya necesitado lambda. Realmente, como dice el tutorial , es solo para el azúcar sintáctico.
Las Lambdas están profundamente vinculadas al estilo de programación funcional en general. La idea de que puede resolver problemas aplicando una función a algunos datos y combinando los resultados, es lo que Google utiliza para implementar la mayoría de sus algoritmos.
Los programas escritos en estilo de programación funcional, son fácilmente paralelizados y, por lo tanto, son cada vez más importantes con las modernas máquinas de múltiples núcleos. Así que en definitiva, NO, no debes olvidarlos.
Las Lambdas son en realidad construcciones muy poderosas que surgen de ideas en la programación funcional, y es algo que de ninguna manera será fácilmente revisado, redefinido o eliminado en el futuro cercano de Python. Le ayudan a escribir código que es más poderoso, ya que le permite pasar funciones como parámetros, por lo tanto, la idea de funciones como ciudadanos de primera clase.
Las Lambdas tienden a confundirse, pero una vez que se obtiene una comprensión sólida, puede escribir código elegante y limpio como este:
squared = map(lambda x: x*x, [1, 2, 3, 4, 5])
La línea de código anterior devuelve una lista de los cuadrados de los números en la lista. Por supuesto, también puedes hacerlo como:
def square(x):
return x*x
squared = map(square, [1, 2, 3, 4, 5])
Es obvio que el código anterior es más corto, y esto es especialmente cierto si pretende usar la función de mapa (o cualquier función similar que tome una función como parámetro) en un solo lugar. Esto también hace que el código sea más intuitivo y elegante.
Además, como lo mencionó @David Zaslavsky en su respuesta, la comprensión de la lista no siempre es el camino a seguir, especialmente si su lista tiene que obtener valores de alguna manera matemática oscura.
Desde un punto de vista más práctico, una de las mayores ventajas de lambdas para mí recientemente ha sido la GUI y la programación dirigida por eventos. Si echa un vistazo a las devoluciones de llamada en Tkinter, todos los que toman como argumentos son el evento que los desencadenó. P.ej
def define_bindings(widget):
widget.bind("<Button-1>", do-something-cool)
def do-something-cool(event):
#Your code to execute on the event trigger
¿Y ahora si tuvieras algunos argumentos para aprobar? Algo tan simple como pasar 2 argumentos para almacenar las coordenadas de un clic del mouse. Puedes hacerlo fácilmente así:
def main():
# define widgets and other imp stuff
x, y = None, None
widget.bind("<Button-1>", lambda event: do-something-cool(x, y))
def do-something-cool(event, x, y):
x = event.x
y = event.y
#Do other cool stuff
Ahora puede argumentar que esto se puede hacer usando variables globales, pero ¿realmente quiere golpearse la cabeza preocupándose por la gestión de la memoria y las fugas, especialmente si la variable global solo se usará en un lugar en particular? Eso sería simplemente un mal estilo de programación.
En resumen, las lambdas son impresionantes y nunca deben ser subestimadas. Las lambdas de Python no son lo mismo que las de LISP (que son más poderosas), pero realmente puedes hacer muchas cosas mágicas con ellas.
Las lambdas son extremadamente útiles en la programación de GUI. Por ejemplo, supongamos que está creando un grupo de botones y desea utilizar una devolución de llamada paramaterizada única en lugar de una devolución de llamada única por botón. Lambda te permite lograrlo con facilidad:
for value in ["one","two","three"]:
b = tk.Button(label=value, command=lambda arg=value: my_callback(arg))
b.pack()
(Nota: aunque esta pregunta es específicamente sobre lambda
, también puede usar functools.partial para obtener el mismo tipo de resultado)
La alternativa es crear una devolución de llamada por separado para cada botón, lo que puede dar lugar a un código duplicado.
No puedo hablar de la implementación particular de python de lambda, pero en general las funciones de lambda son realmente útiles. Son una técnica básica (tal vez incluso LA TÉCNICA) de la programación funcional, y también son muy útiles en programas orientados a objetos. Para ciertos tipos de problemas, son la mejor solución, ¡por lo que no debe olvidarse!
Le sugiero que lea los Closures y la función de mapa (que enlaza con los documentos de Python, pero existe en casi todos los idiomas que admiten construcciones funcionales) para ver por qué es útil.
Primeros felicidades que lograron descifrar lambda. En mi opinión, esta es una construcción realmente poderosa para actuar. La tendencia en estos días hacia los lenguajes de programación funcionales es seguramente un indicador de que no se debe evitar ni se redefinirá en un futuro próximo.
Solo tienes que pensar un poco diferente. Estoy seguro de que pronto te encantará. Pero ten cuidado si solo tratas con python. Debido a que la lambda no es un cierre real, se "rompe" de alguna manera: las pitones lambda se rompen
Un lambda es parte de un mecanismo de abstracción muy importante que trata con funciones de orden superior. Para obtener una comprensión adecuada de su valor, observe las lecciones de alta calidad de Abelson y Sussman , y lea el libro SICP
Estos son temas relevantes en el negocio de software moderno, y cada vez son más populares.
Una de las cosas agradables sobre lambda
que, en mi opinión, es subestimada es que es una forma de diferir una evaluación de formas simples hasta que se necesita el valor. Dejame explicar.
Muchas rutinas de la biblioteca se implementan de modo que permiten que ciertos parámetros sean callables (de los cuales lambda es uno). La idea es que el valor real se calculará solo en el momento en que se utilizará (y no cuando se llame). Un ejemplo (creado) podría ayudar a ilustrar el punto. Supongamos que tiene una rutina que iba a registrar una marca de tiempo determinada. Desea que la rutina utilice la hora actual menos 30 minutos. Usted lo llamaría así
log_timestamp(datetime.datetime.now() - datetime.timedelta(minutes = 30))
Ahora suponga que la función real se llamará solo cuando ocurra cierto evento y desea que la marca de tiempo se calcule solo en ese momento. Puedes hacerlo así
log_timestamp(lambda : datetime.datetime.now() - datetime.timedelta(minutes = 30))
Asumiendo que log_timestamp
puede manejar log_timestamp
esta manera, evaluará esto cuando lo necesite y obtendrá la marca de tiempo en ese momento.
Por supuesto, hay formas alternativas de hacer esto (utilizando el módulo del operator
, por ejemplo) pero espero haber transmitido el punto.
Actualización : Here hay un ejemplo del mundo real un poco más concreto.
Actualización 2 : creo que este es un ejemplo de lo que se llama un thunk .
Yo uso lambdas para evitar la duplicación de código. Haría la función fácilmente comprensible, por ejemplo:
def a_func()
...
if some_conditon:
...
call_some_big_func(arg1, arg2, arg3, arg4...)
else
...
call_some_big_func(arg1, arg2, arg3, arg4...)
Reemplazo eso con un temp lambda
def a_func()
...
call_big_f = lambda args_that_change: call_some_big_func(arg1, arg2, arg3, args_that_change)
if some_conditon:
...
call_big_f(argX)
else
...
call_big_f(argY)
lambda
es solo una forma elegante de decir function
. Aparte de su nombre, no hay nada oscuro, intimidante o críptico al respecto. Cuando lea la siguiente línea, reemplace lambda
por function
en su mente:
>>> f = lambda x: x + 1
>>> f(3)
4
Simplemente define una función de x
. Algunos otros lenguajes, como R
, lo dicen explícitamente:
> f = function(x) { x + 1 }
> f(3)
4
¿Lo ves? Es una de las cosas más naturales para hacer en programación.
La función Lambda es una forma no burocrática de crear una función.
Eso es. Por ejemplo, supongamos que tiene su función principal y necesita cuadrar los valores. Veamos la forma tradicional y la forma lambda de hacer esto:
Forma tradicional:
def main():
...
...
y = square(some_number)
...
return something
def square(x):
return x**2
La forma lambda:
def main():
...
square = lambda x: x**2
y = square(some_number)
return something
¿Ver la diferencia?
Las funciones Lambda van muy bien con listas, como listas de comprensión o mapa. De hecho, la comprensión de lista es una forma "pythonic" de expresarte usando lambda. Ex:
>>>a = [1,2,3,4]
>>>[x**2 for x in a]
[1,4,9,16]
Veamos qué significa cada elemento de la sintaxis:
[]: "Dame una lista"
x ** 2: "usando esta función recién nacida"
para x en a: "en cada elemento en a"
Eso es conveniente uh? Creando funciones como esta. Vamos a reescribirlo usando lambda:
>>> square = lambda x: x**2
>>> [square(s) for x in a]
[1,4,9,16]
Ahora usemos el mapa, que es lo mismo, pero más neutral en cuanto al idioma. Mapas lleva 2 argumentos:
(i) una función
(ii) un iterable
Y le da una lista donde cada elemento es la función aplicada a cada elemento de lo iterable.
Entonces, usando el mapa tendríamos:
>>> a = [1,2,3,4]
>>> squared_list = map(lambda x: x**2, a)
Si dominas las lambdas y el mapeo, tendrás un gran poder para manipular los datos de una manera concisa. Las funciones Lambda no son oscuras ni eliminan la claridad del código. No confundas algo duro con algo nuevo. Una vez que comiences a usarlos, lo encontrarás muy claro.
Comencé a leer el libro de David Mertz hoy ''Procesamiento de texto en Python''. Si bien él tiene una descripción bastante breve de los ejemplos de Lambda en el primer capítulo, combinados con la explicación en el Apéndice A, los hizo saltar de la página para mí (finalmente) y de repente comprendí su valor. Eso no quiere decir que su explicación funcionará para usted y todavía estoy en la etapa de descubrimiento, así que no intentaré agregar a estas respuestas más que las siguientes: Soy nuevo en Python Soy nuevo en OOP Lambdas fue una lucha para mí Ahora que leo Mertz, creo que los recibo y los veo muy útiles, ya que creo que permiten un enfoque más limpio de la programación.
Reproduce el Zen de Python, una línea de la cual es Simple es mejor que compleja. Como programador que no trabaja en OOP, lee el código con lambdas (y hasta la semana pasada, enumera las comprensiones) que he pensado: ¿ esto es simple? .Finalmente me di cuenta hoy que en realidad estas características hacen que el código sea mucho más legible y comprensible que la alternativa, que es invariablemente un bucle de algún tipo. También me di cuenta de que, al igual que los estados financieros, Python no estaba diseñado para el usuario principiante, sino que está diseñado para el usuario que desea educarse. No puedo creer lo poderoso que es este lenguaje. Cuando se me ocurrió (finalmente) el propósito y el valor de las lambdas, quise romper unos 30 programas y comenzar a colocar lambdas cuando sea apropiado.
Lambda es un constructor de procedimientos. Puedes sintetizar programas en tiempo de ejecución, aunque la lambda de Python no es muy poderosa. Tenga en cuenta que pocas personas entienden ese tipo de programación.
Lo uso bastante a menudo, principalmente como un objeto nulo o para enlazar parcialmente parámetros a una función.
Aquí hay algunos ejemplos:
para implementar un patrón de objeto nulo:
{
DATA_PACKET: self.handle_data_packets
NET_PACKET: self.handle_hardware_packets
}.get(packet_type, lambda x : None)(payload)
para vinculación de parámetros:
Digamos que tengo la siguiente API
def dump_hex(file, var)
# some code
pass
class X(object):
#...
def packet_received(data):
# some kind of preprocessing
self.callback(data)
#...
Luego, cuando no quiero descargar rápidamente los datos recibidos en un archivo, hago eso:
dump_file = file(''hex_dump.txt'',''w'')
X.callback = lambda (x): dump_hex(dump_file, x)
...
dump_file.close()
Puedo darte un ejemplo donde realmente necesito lambda seria. Estoy haciendo un programa gráfico, donde el uso hace clic derecho en un archivo y le asigna una de las tres opciones. Resulta que en Tkinter (el programa de interfaz GUI en el que escribo esto), cuando alguien presiona un botón, no se puede asignar a un comando que recibe argumentos. Entonces, si elegí una de las opciones y quería que el resultado de mi elección fuera:
print ''hi there''
Entonces no es gran cosa. Pero qué pasa si necesito mi elección para tener un detalle particular. Por ejemplo, si elijo la opción A, llama a una función que toma algún argumento que depende de la opción A, B o C, TKinter no podría admitir esto. Lamda fue la única opción para solucionar esto en realidad ...
Soy un principiante de python, así que para tener una idea clara de Lambda lo comparé con un bucle ''for''; en términos de eficiencia. Aquí está el código (python 2.7) -
import time
start = time.time() # Measure the time taken for execution
def first():
squares = map(lambda x: x**2, range(10))
# ^ Lambda
end = time.time()
elapsed = end - start
print elapsed + '' seconds''
return elapsed # gives 0.0 seconds
def second():
lst = []
for i in range(10):
lst.append(i**2)
# ^ a ''for'' loop
end = time.time()
elapsed = end - start
print elapsed + '' seconds''
return elapsed # gives 0.0019998550415 seconds.
print abs(second() - first()) # Gives 0.0019998550415 seconds!(duh)
Un caso útil para usar las lambdas es mejorar la legibilidad de las comprensiones de listas largas . En este ejemplo loop_dic
es corto para mayor claridad pero imagina loop_dic
ser muy largo. Si solo usara un valor simple que incluya en i
lugar de la versión lambda de ese valor, obtendría un NameError
.
>>> lis = [{"name": "Peter"}, {"name": "Josef"}]
>>> loop_dic = lambda i: {"name": i["name"] + " Wallace" }
>>> new_lis = [loop_dic(i) for i in lis]
>>> new_lis
[{''name'': ''Peter Wallace''}, {''name'': ''Josef Wallace''}]
En lugar de
>>> lis = [{"name": "Peter"}, {"name": "Josef"}]
>>> new_lis = [{"name": i["name"] + " Wallace"} for i in lis]
>>> new_lis
[{''name'': ''Peter Wallace''}, {''name'': ''Josef Wallace''}]
Yo uso lambda
para crear devoluciones de llamada que incluyen parámetros. Es más limpio escribir un lambda en una línea que escribir un método para realizar la misma funcionalidad.
Por ejemplo:
import imported.module
def func():
return lambda: imported.module.method("foo", "bar")
Opuesto a:
import imported.module
def func():
def cb():
return imported.module.method("foo", "bar")
return cb