Godot: GDScript: funciones variables (número variable de argumentos / varargs)

Creado en 11 feb. 2018  ·  29Comentarios  ·  Fuente: godotengine/godot

Descripcion del problema:
Agregue soporte para funciones variadas a GDScript.

Esto sería principalmente azúcar sintáctico, transformando:

func f(args):
    for x in args:
        # Do something with x

f(["these", "are", "some", "arguments"])

dentro:

func f(args...):
    for x in args:
        # Do something with x

f("these", "are", "some", "arguments")
archived feature proposal gdscript

Comentario más útil

Creo que esta característica es realmente necesaria ya que hay algunas funciones que ya son varargs pero no tenemos forma de anularlas.

image

Todos 29 comentarios

Para que entienda esto correctamente, ¿estamos hablando de algo como el operador de splat de Ruby ?

La última vez que sugerí algo para gdscript, reduz lo cerró y lo rechazó bastante rápido, así que solo una advertencia (¡estoy votando sí por cierto, gl!)

@ LikeLakers2 De un vistazo breve, sí exactamente.

@girng Bueno, espero que eso realmente dependa de la función sugerida. Honestamente, incluso esto es más agradable tener uno; Puedo vivir sin él, pero haría que algunos casos comunes fueran un poco más agradables.

Ah, entonces esta idea tiene mi apoyo. Ese operador de símbolo es muy útil en Ruby.

La función multijugador de alto nivel rpc ya hace esto. ¿La forma en que lo hace es accesible de alguna manera?

Me gustaría que esto pudiera implementar una función de registro personalizada y simple.

Ya podemos hacer lo siguiente:

print("Score: ", score)

pero sería bueno poder hacer también lo siguiente:

_log("Score: ", score)

donde la salida de log produciría:

[MyClass] Score: 500

Me gustaría que esto pudiera implementar una función de registro personalizada y simple.

Ya podemos hacer lo siguiente:

print("Score: ", score)

pero sería bueno poder hacer también lo siguiente:

_log("Score: ", score)

donde la salida de log produciría:

[MyClass] Score: 500

¿Puedo más uno esto ... también quiero hacer una función de impresión que imprima normalmente como en Python (cadenas y números, etc.) ya que encuentro la impresión desagradable, pero tal vez a otras personas les guste?

Creo que esta sería una característica realmente asombrosa en gdscript. Tener la capacidad de pasar múltiples argumentos sin una matriz sería muy útil en casos como las funciones de registro personalizadas.

Si bien podría argumentar que puede salirse con la suya en lo que respecta a la creación de un juego (y estaría absolutamente en lo cierto), sería una característica increíblemente beneficiosa para los fabricantes de herramientas de Godot que quieran "" "exponer" "" un API flexible para sus usuarios.

exponer está entre comillas porque técnicamente todo está expuesto en cierto sentido.

Creo que esta característica es realmente necesaria ya que hay algunas funciones que ya son varargs pero no tenemos forma de anularlas.

image

Me encantaría varargs en gdscript. Considerar:

func rpc_game_info(node:Node, method:String, args:vararg):
    for id in players:
        node.rpc_id(id, method, args)

La única forma en que puedo pensar en implementar esto actualmente es copiar y pegar las dos líneas en todos rpc_game_info donde se llamaría

¿Existe al menos una forma de desenrollar / extender / expandir una matriz? En otras palabras, ¿hay alguna manera de hacer que algo como esto funcione ?:

func foo(bar: String, args = []):
  baz(bar, ...args)

@rosshadden puedes usar Object::callv("method", [..args])

He estado escribiendo mucho código C / C ++ / Js para sitios web, backends, juegos desde 2012, y no puedo recordar una situación en la que necesitaba absolutamente usar varargs. Es una buena característica para registrar mensajes de depuración, pero aparte de eso, no veo ninguna necesidad. De hecho, he estado haciendo juegos de Godot durante más de un año y estoy bastante contento con donde gdscript ahora: hace todo lo que necesito y más. En lugar de perder tiempo agregando campanas y silbidos adicionales al lenguaje, prefiero votar por mejorar la eficiencia de la funcionalidad existente. Saludos cordiales, - Alexandre Kharlamov

He estado escribiendo mucho código C / C ++ / Js para sitios web, backends, juegos desde 2012, y no puedo recordar una situación en la que necesitaba absolutamente usar varargs. Es una buena característica para registrar mensajes de depuración, pero aparte de eso, no veo ninguna necesidad. De hecho, he estado haciendo juegos de Godot durante más de un año y estoy bastante contento con donde gdscript ahora: hace todo lo que necesito y más. En lugar de perder tiempo agregando campanas y silbidos adicionales al lenguaje, prefiero votar por mejorar la eficiencia de la funcionalidad existente. Saludos cordiales, - Alexandre Kharlamov

Eso es bueno, pero lamento decir que su voto no significa nada cuando es probable que un voluntario lo implemente por su propia voluntad.

@mitchcurtis Por favor, absténgase de hacer comentarios que no estén relacionados con el tema discutido. Restar importancia a los demás no contribuye positivamente a la discusión.

¿Cómo es que llamar "campanas y silbatos" a una función que muchos están pidiendo no restar importancia a los demás? Mi comentario está directamente relacionado con el problema en cuestión: es un proyecto de código abierto y muchas de las confirmaciones son de colaboradores que eligen en qué quieren trabajar.

Démosle la vuelta: ¿el comentario de Alexandre contribuye positivamente a la discusión? ¿No habría sido mejor para él encontrar una característica específica que le interesara y mostrar su apoyo en lugar de restar importancia a las características que otros quieren?

Implementar funciones no se trata solo de "quién lo quiere" y "quién puede implementarlo". También es importante saber "quién piensa que no es necesario (y por qué)", ya que debemos evitar implementar funciones si en realidad no las necesitamos. Hacen que el mantenimiento del código sea más difícil, pueden afectar el rendimiento, reducir las posibilidades de optimización, etc. (especialmente en un lenguaje de scripting).

Así que sí, la retroalimentación de @alexkh es interesante, incluso si no está de acuerdo con ella. Alguien puede venir con un PR perfecto para esta función mañana, los colaboradores principales todavía necesitarán dedicar bastante tiempo a pensar y debatir si vale la pena agregar esto desde un punto de vista técnico y de diseño de API.

Mantener el alcance de GDScript pequeño y fácil de mantener es definitivamente uno de los principios básicos de diseño del lenguaje. No digo que esta característica específica no sea una buena adición, pero tenemos que sopesar los pros y los contras, lo que implica escuchar a quienes no están de acuerdo con la propuesta.

Implementar funciones no se trata solo de "quién lo quiere" y "quién puede implementarlo". También es importante saber "quién piensa que no es necesario (y por qué)", ya que debemos evitar implementar funciones si en realidad no las necesitamos. Hacen que el mantenimiento del código sea más difícil, pueden afectar el rendimiento, reducir las posibilidades de optimización, etc. (especialmente en un lenguaje de scripting).

Así que sí, la retroalimentación de @alexkh es interesante, incluso si no está de acuerdo con ella. Alguien puede venir con un PR perfecto para esta función mañana, los colaboradores principales todavía necesitarán dedicar bastante tiempo a pensar y debatir si vale la pena agregar esto desde un punto de vista técnico y de diseño de API.

Mantener el alcance de GDScript pequeño y fácil de mantener es definitivamente uno de los principios básicos de diseño del lenguaje. No digo que esta característica específica no sea una buena adición, pero tenemos que sopesar los pros y los contras, lo que implica escuchar a quienes no están de acuerdo con la propuesta.

Puntos justos.

Creo que la cantidad de votos para este tema habla por sí sola, pero intentaré abstenerme de hacer tales comentarios en el futuro.

He estado escribiendo mucho código C / C ++ / Js para sitios web, backends, juegos desde 2012, y no puedo recordar una situación en la que necesitaba absolutamente usar varargs. Es una buena característica para registrar mensajes de depuración, pero aparte de eso, no veo ninguna necesidad. De hecho, he estado haciendo juegos de Godot durante más de un año y estoy bastante contento con donde gdscript ahora: hace todo lo que necesito y más. En lugar de perder tiempo agregando campanas y silbidos adicionales al lenguaje, prefiero votar por mejorar la eficiencia de la funcionalidad existente. Saludos cordiales, - Alexandre Kharlamov

Estoy programando en varios juegos, programas tanto en casa como en el trabajo durante más de 15 años, pero solo durante 1 mes en godot y puedo decir que extraño varias funciones, que ya están abiertas como solicitud de función en particular. Esta característica. ser capaz de aceptar y enviar números variables de argumentos es algo que necesito con bastante frecuencia y está disminuyendo la calidad del código drásticamente si tiene que solucionarlo.

Un ejemplo: => herencia

class A
_init(arg0, arg1, arg2)

class B extends A
_init(arg0, arg1, arg2, arg4).(arg0, arg1, arg2)

Ahora imagina que tienes que cambiar la lista de argumentos de la clase A. Tendrás que encontrar todas las clases que hereden esta clase, que sean peligrosas. A pesar de que no hay argumentos con nombre, mezclar la lista de argumentos no es un problema en sí mismo.

Otro ejemplo son las devoluciones de llamada, supongo que esto va sin código ...

Así que mi punto es: godot no hace todo lo que necesitas todavía, solo hace todo lo que es crucial (bueno y, por supuesto, bastante más :) ...). Sin embargo, todavía no ha llegado a un punto en el que dejar de añadir funciones sería el mejor caso. Sin embargo, tener cuidado con lo que agregar es una buena decisión.

Editar: Me acabo de dar cuenta de que otro buen ejemplo es el método Object.call () de godot;)

DamKoVosh, por favor dime, ¿cuántas líneas de código fue tu juego más grande? Cada vez que hago un juego me decepciona la poca codificación que requiere. La mayor parte del trabajo es siempre el contenido, las pruebas y el equilibrio del juego. Estás diciendo que reescribir es peligroso. Si nada más, reescribir su código lo hace mejor para escribir interfaces y estructuras de datos preparadas para el futuro.

Como se indicó en el primer mensaje de este hilo, toda la discusión es exactamente sobre el azúcar sintáctico para algo que ya se puede implementar fácilmente usando una matriz en lugar de implementar una función variada.

@alexkh

Como se indicó en el primer mensaje de este hilo, toda la discusión es exactamente sobre el azúcar sintáctico para algo que ya se puede implementar fácilmente usando una matriz en lugar de implementar una función variada.

Como dijo anteriormente Geequlim , esto no es solo azúcar sintáctico, sino que en realidad rompe la capacidad de anular funciones que usan varargs, como rpc , emit_signal , ... Me encontré con ese problema cuando Intenté cambiar rpc según mis necesidades.

Sí, es azúcar sintáctico. Sin embargo, ser azúcar sintáctico no significa que sean buenos o malos. Controle el flujo como if , else e incluso las funciones son solo azúcar además de GOTO también, si así lo desea. Eso no significa que no los quieras.

A veces, agregar un poco de azúcar sintáctico hace que el código sea mucho más legible y vale la pena la complejidad adicional.

pero en realidad rompe la capacidad de anular funciones que usan varargs, como rpc, emit_signal

Es curioso que esas funciones utilicen varargs y no matrices. ;-) ¿Observa cómo la propia API de Godot usa varargs en varios lugares? Probablemente haya una razón para eso.

También es curioso saber cuántos lenguajes implementan funciones variadas. ¿Quizás sean útiles incluso si se pueden "implementar fácilmente usando una matriz"?

Los extraño mucho en GDScript cada vez que lo uso, y es una de las razones por las que prefiero C #. O C ++. O Java. O Python. O ir.

Honestamente, creo que GDScript es el único idioma en el que he trabajado que no los tiene. Además, ¿quizás, Lua? Ah, lo comprobé y parece que también existen allí. No digo que debamos apuntar a agregar todo lo que esos lenguajes tienen a GDScript, pero si todos tienen una característica en común, puede que valga la pena.

No puedo juzgar cuánta complejidad agregaría al backend de GDScript y, por lo tanto, no puedo decir mucho sobre la compensación de la complejidad, pero descartarlos porque son "solo azúcar sintáctico" es incorrecto, porque eso se puede decir sobre un montón de cosas.

Nuevamente, observe cuántas cosas en Godot los usan.

Sí, es azúcar sintáctico. Sin embargo, ser azúcar sintáctico no significa que sean buenos o malos. Controle el flujo como if , else e incluso las funciones son solo azúcar además de GOTO también, si así lo desea. Eso no significa que no los quieras.

GOTO no reemplaza si porque es un salto incondicional. ¿Eres siquiera un programador?

pero en realidad rompe la capacidad de anular funciones que usan varargs, como rpc, emit_signal

una vez al año, alguien en algún lugar querrá anular la función rpc. Mientras que miles de personas cada día desean ver a Godot 4 lanzado.

También es curioso saber cuántos lenguajes implementan funciones variadas. ¿Quizás sean útiles incluso si se pueden "implementar fácilmente usando una matriz"?

Los extraño mucho en GDScript cada vez que lo uso, y es una de las razones por las que prefiero C #. O C ++. O Java. O Python. O ir.

C ++ no tiene un tipo de matriz estándar que pueda almacenar valores de diferentes tipos como lo hace GDscript. Aunque C ++ admite funciones variadas, se desaconseja su uso porque no es seguro. Es un legado de C, y en C en sí mismo era un azúcar sintáctico, porque printf se usaba mucho, especialmente para depurar, donde desea escribir rápidamente código temporal para generar algunos datos. Estaba totalmente justificado, porque se usaba todo el tiempo, ¡un ahorro de tiempo real! Pero, ¿alguna vez escribió su propia función variada en C o C ++?

Nuevamente, observe cuántas cosas en Godot los usan.

Para la salida de depuración, ¡por supuesto! Pero si print () no fuera variadic, en lugar de print ("Hola", "Mundo), tendrías que escribir print ([" Hola "," Mundo "]) - no es una gran diferencia en absoluto ...

GOTO no reemplaza si porque es un salto incondicional

Bueno, cierto. Estaba hablando de saltos condicionales, por supuesto. Lo cual ... probablemente podrías inferir. Aún así, el punto se mantiene: hemos construido una funcionalidad de mayor nivel en la parte superior para poder transmitir algunas cosas de manera más limpia.

C ++ no tiene un tipo de matriz estándar que pueda almacenar valores de diferentes tipos como lo hace GDscript.

Bien, discuta en contra de Python, Lua o Go (o cualquier otro lenguaje), entonces los tienen y aún tienen funciones variadas.

Pero si print () no fuera variadic, en lugar de print ("Hola", "Mundo), tendrías que escribir print ([" Hola "," Mundo "]) - no es una gran diferencia en absoluto

Claro, en ese simple caso de prueba. En los más complejos, se vuelve más feo, especialmente una vez que comienza a tener datos de múltiples fuentes y ahora necesita rellenarlos manualmente en una matriz primero. Estoy de acuerdo en que no es una gran pérdida; aún así, las funciones variadas hacen que el código sea más limpio en algunos casos.

Pero...

Pero, ¿alguna vez escribió su propia función variada en C o C ++?

¿Eres siquiera un programador?

Como se indicó anteriormente, no siento que esté discutiendo de buena fe. En cuyo caso ya no estoy realmente interesado en hablar contigo, así que ... no, solo estoy en la lista como colaborador del motor porque soy una buena mascota, sigue adelante.

GOTO no reemplaza si porque es un salto incondicional. ¿Eres siquiera un programador?

En su mayor parte, los enunciados condicionales, especialmente los bucles, son solo un enunciado de salto especializado, que es casi lo mismo que un enunciado goto, en un sentido práctico, la mayoría de los enunciados básicos de control de secuencia que encuentras son una extensión de eso. Este es un argumento tonto para apoyarse (ya que en realidad no es un argumento, solo argumenta semántica que es inútil) y esa segunda parte es una falta de respeto.

C ++ no tiene un tipo de matriz estándar que pueda almacenar valores de diferentes tipos como lo hace GDscript. Aunque C ++ admite funciones variadas, se desaconseja su uso porque no es seguro. Es un legado de C, y en C en sí mismo era un azúcar sintáctico, porque printf se usaba mucho, especialmente para depurar, donde desea escribir rápidamente código temporal para generar algunos datos. Estaba totalmente justificado, porque se usaba todo el tiempo, ¡un ahorro de tiempo real! Pero, ¿alguna vez escribió su propia función variada en C o C ++?

Si bien C ++ no tiene un tipo de matriz estándar para varargs (o matrices sin tipo en general), primero existen formas de lidiar con esto desde hace aproximadamente una década (técnicamente, podría hacer esto incluso antes de C ++ 11, sin embargo, era muy pesado en macros y bastante hacky) y, en segundo lugar, con las plantillas varadic puede omitir por completo los problemas de mecanografía. Hay maneras de lidiar con varargs en C ++ usando plantillas varadic. Aquellos que todavía creen en varargs en C ++ probablemente estén comenzando desde el punto equivocado en estos días.

No me importa mucho la discusión personalmente (aparte de que personalmente me parece más limpio y organizado tener algún tipo de argumentos varadic basados ​​en matrices en GDScript en lugar de sentarse en el backend, creo que las características del lenguaje deberían implementarse para el lenguaje, no solo su ejecución, sino que soy solo yo), pero estos comentarios necesitaban ser corregidos, y aparte de que estás actuando bastante grosero en este caso, no refuerzas tu punto de vista en la mente de tu audiencia cuando responder negativamente a la oposición que debe manejarse objetivamente de esta manera.

GOTO no reemplaza si porque es un salto incondicional. ¿Eres siquiera un programador?

En su mayor parte, los enunciados condicionales, especialmente los bucles, son solo un enunciado de salto especializado, que es casi lo mismo que un enunciado goto, en un sentido práctico, la mayoría de los enunciados básicos de control de secuencia que encuentras son una extensión de eso. Este es un argumento tonto para apoyarse (ya que en realidad no es un argumento, solo argumenta semántica que es inútil) y esa segunda parte es una falta de respeto.

K, soy irrespetuoso con las personas que me hacen perder el tiempo. Su punto era: ¿por qué no usar GOTO en lugar de if? Y dije que GOTO no reemplaza if. GOTO no es una declaración condicional y si desea reemplazar la declaración condicional, simplemente escriba exactamente con qué desea reemplazarla. ¿Algún ejemplo ya?

C ++ no tiene un tipo de matriz estándar que pueda almacenar valores de diferentes tipos como lo hace GDscript. Aunque C ++ admite funciones variadas, se desaconseja su uso porque no es seguro. Es un legado de C, y en C en sí mismo era un azúcar sintáctico, porque printf se usaba mucho, especialmente para depurar, donde desea escribir rápidamente código temporal para generar algunos datos. Estaba totalmente justificado, porque se usaba todo el tiempo, ¡un ahorro de tiempo real! Pero, ¿alguna vez escribió su propia función variada en C o C ++?

Si bien C ++ no tiene un tipo de matriz estándar para varargs (o matrices sin tipo en general), primero existen formas de lidiar con esto desde hace aproximadamente una década (técnicamente, podría hacer esto incluso antes de C ++ 11, sin embargo, era muy pesado en macros y bastante hacky) y, en segundo lugar, con las plantillas varadic puede omitir por completo los problemas de mecanografía. Hay maneras de lidiar con varargs en C ++ usando plantillas varadic. Aquellos que todavía creen en varargs en C ++ probablemente estén comenzando desde el punto equivocado en estos días.

No me importa mucho la discusión personalmente (aparte de que personalmente me parece más limpio y organizado tener algún tipo de argumentos varadic basados ​​en matrices en GDScript en lugar de sentarse en el backend, creo que las características del lenguaje deberían implementarse para el lenguaje, no solo su ejecución, sino que soy solo yo), pero estos comentarios necesitaban ser corregidos, y aparte de que estás actuando bastante grosero en este caso, no refuerzas tu punto de vista en la mente de tu audiencia cuando responder negativamente a la oposición que debe manejarse objetivamente de esta manera.

K, pero ese es exactamente mi punto: GDscript tiene un tipo estándar que puede iterar que puede contener diferentes tipos, por lo que no necesita meterse con toda la piratería necesaria para que las funciones variadas funcionen en C ++, y es por eso que , quizás, en C ++ las plantillas variadas están justificadas.

K, soy irrespetuoso con las personas que me hacen perder el tiempo.

Luego, te dejaré perder el tiempo en otros proyectos, ya que ahora no puedes interactuar en los repositorios de @godotengine durante 30 días.

Tenemos un Código de Conducta y definitivamente no permite ser irrespetuoso con nadie .

Las propuestas de funciones y mejoras para Godot Engine ahora se están discutiendo y revisando en un rastreador de problemas de Godot Improvement Proposals (GIP) ( godotengine / godot-proposits ). El rastreador GIP tiene una plantilla detallada de problemas diseñada para que las propuestas incluyan toda la información relevante para iniciar una discusión productiva y ayudar a la comunidad a evaluar la validez de la propuesta para el motor.

El rastreador principal ( extracción , lo que permite a los colaboradores tener un mejor enfoque en el trabajo de corrección de errores. Por lo tanto, ahora cerramos todas las propuestas de funciones más antiguas en el rastreador de problemas principal.

Si está interesado en esta propuesta de función, abra una nueva propuesta en el rastreador de GIP siguiendo la plantilla de problema dada (después de verificar que aún no existe). Asegúrese de hacer referencia a este tema cerrado si incluye alguna discusión relevante (que también se le anima a resumir en la nueva propuesta). ¡Gracias por adelantado!

¿Fue útil esta página
0 / 5 - 0 calificaciones