Godot: GDScript: funções variáveis ​​(número variável de argumentos / varargs)

Criado em 11 fev. 2018  ·  29Comentários  ·  Fonte: godotengine/godot

Descrição do problema:
Adicione suporte para funções variáveis ​​ao GDScript.

Isso seria principalmente açúcar sintático, transformando:

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

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

em:

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

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

Comentários muito úteis

Acho que esse recurso é realmente necessário, pois algumas funções já são varargs mas não temos como substituí-las.

image

Todos 29 comentários

Só para eu entender isso corretamente, estamos falando de algo como o operador splat de Ruby ?

da última vez que sugeri algo para o gdscript, ele foi encerrado e evitado por reduz muito rápido, então apenas um aviso (estou votando sim btw, gl!)

@ LikeLakers2 Em uma breve olhada, sim, exatamente.

@girng Bem, espero que realmente dependa do recurso sugerido. Honestamente, até isso é mais agradável ter um; Posso viver sem isso, mas tornaria alguns casos comuns um pouco mais agradáveis.

Bem, então essa ideia tem meu apoio. Esse operador splat é muuuuito útil em Ruby.

A função multijogador de alto nível rpc já faz isso. A forma como o faz é acessível de alguma forma?

Gostaria que isso fosse capaz de implementar uma função de registro simples e personalizada.

Já podemos fazer o seguinte:

print("Score: ", score)

mas seria bom poder também fazer o seguinte:

_log("Score: ", score)

onde a saída do log produziria:

[MyClass] Score: 500

Gostaria que isso fosse capaz de implementar uma função de registro simples e personalizada.

Já podemos fazer o seguinte:

print("Score: ", score)

mas seria bom poder também fazer o seguinte:

_log("Score: ", score)

onde a saída do log produziria:

[MyClass] Score: 500

posso mais um isso ... também quero fazer uma função de impressão que irá imprimir normalmente como em python (strings e números etc), pois acho a impressão desagradável, mas talvez outras pessoas gostem

Acho que esse seria um recurso realmente incrível no gdscript. Ter a capacidade de passar vários argumentos sem uma matriz seria muito útil em casos como funções de log personalizadas!

Embora você possa argumentar que pode se safar com isso no que diz respeito a fazer um jogo (e você estaria absolutamente certo), seria um recurso benéfico incrível para fabricantes de ferramentas para o próprio Godot que desejam "" "expor" "" um API flexível para seus usuários.

expor está entre aspas porque, tecnicamente, tudo está exposto em certo sentido.

Acho que esse recurso é realmente necessário, pois algumas funções já são varargs mas não temos como substituí-las.

image

Eu adoraria varargs em gdscript. Considerar:

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

A única maneira que consigo pensar em implementar isso atualmente é copiar e colar as duas linhas em todos os lugares que rpc_game_info seriam chamados e fornecer o método args como uma lista separada por vírgulas.

Existe pelo menos uma maneira de desenrolar / espalhar / expandir um array? Em outras palavras, existe uma maneira de fazer algo assim funcionar ?:

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

@rosshadden você pode usar Object::callv("method", [..args])

Eu tenho escrito muito código C / C ++ / Js para sites, back-ends, jogos desde 2012, e não me lembro de uma situação em que eu absolutamente precisei usar varargs. É um bom recurso para registrar mensagens de depuração, mas além disso, não vejo nenhuma necessidade para ele. Na verdade, faço jogos Godot há mais de um ano e estou muito feliz com o gdscript onde agora: faz tudo o que preciso e muito mais. Em vez de perder tempo adicionando sinos e apitos extras ao idioma, prefiro votar para melhorar a eficiência da funcionalidade existente. Atenciosamente, - Alexandre Kharlamov

Eu tenho escrito muito código C / C ++ / Js para sites, back-ends, jogos desde 2012, e não me lembro de uma situação em que eu absolutamente precisei usar varargs. É um bom recurso para registrar mensagens de depuração, mas além disso, não vejo nenhuma necessidade para ele. Na verdade, faço jogos Godot há mais de um ano e estou muito feliz com o gdscript onde agora: faz tudo o que preciso e muito mais. Em vez de perder tempo adicionando sinos e apitos extras ao idioma, prefiro votar para melhorar a eficiência da funcionalidade existente. Atenciosamente, - Alexandre Kharlamov

Isso é bom, mas lamento dizer que seu voto não significa nada quando é provável que um voluntário o implemente por sua própria vontade.

@mitchcurtis Por favor, evite fazer comentários que não estejam relacionados ao assunto discutido. Menosprezar os outros não contribui positivamente para a discussão.

Como chamar um recurso que muitos estão pedindo "sinos e assobios" não minimiza os outros? Meu comentário está diretamente relacionado ao problema em questão - é um projeto de código aberto e muitos dos commits são de contribuidores que escolhem no que querem trabalhar.

Vamos inverter: o comentário de Alexandre contribui positivamente para a discussão? Não teria sido melhor para ele encontrar um recurso específico no qual estivesse interessado e mostrar apoio a ele, em vez de minimizar os recursos que os outros desejam?

Implementar recursos não se trata apenas de "quem deseja" e "quem pode implementá-lo". Também é importante saber "quem acha que não é necessário (e por quê)", pois devemos evitar a implementação de recursos se realmente não precisarmos deles. Eles tornam a manutenção do código mais difícil, podem afetar o desempenho, reduzir as possibilidades de otimização, etc. (especialmente em uma linguagem de script).

Então, sim, o feedback de @alexkh é interessante, mesmo se você não concordar com ele. Alguém pode vir com um RP perfeito para esse recurso amanhã; os principais colaboradores ainda precisarão gastar algum tempo pensando e debatendo se vale a pena adicionar do ponto de vista técnico e de design de API.

Manter o escopo do GDScript pequeno e fácil de manter é definitivamente um dos princípios básicos de design para a linguagem. Não estou dizendo que esse recurso específico não seria um bom acréscimo, mas temos que pesar os prós e os contras, o que implica ouvir quem discorda da proposta.

Implementar recursos não se trata apenas de "quem deseja" e "quem pode implementá-lo". Também é importante saber "quem acha que não é necessário (e por quê)", pois devemos evitar a implementação de recursos se realmente não precisarmos deles. Eles tornam a manutenção do código mais difícil, podem afetar o desempenho, reduzir as possibilidades de otimização, etc. (especialmente em uma linguagem de script).

Então, sim, o feedback de @alexkh é interessante, mesmo se você não concordar com ele. Alguém pode vir com um RP perfeito para esse recurso amanhã; os principais colaboradores ainda precisarão gastar algum tempo pensando e debatendo se vale a pena adicionar do ponto de vista técnico e de design de API.

Manter o escopo do GDScript pequeno e fácil de manter é definitivamente um dos princípios básicos de design para a linguagem. Não estou dizendo que esse recurso específico não seria um bom acréscimo, mas temos que pesar os prós e os contras, o que implica ouvir quem discorda da proposta.

Pontos justos.

Penso que o número de votos para esta questão fala por si, mas tentarei abster-me de fazer tais comentários no futuro.

Eu tenho escrito muito código C / C ++ / Js para sites, back-ends, jogos desde 2012, e não me lembro de uma situação em que eu absolutamente precisei usar varargs. É um bom recurso para registrar mensagens de depuração, mas além disso, não vejo nenhuma necessidade para ele. Na verdade, faço jogos Godot há mais de um ano e estou muito feliz com o gdscript onde agora: faz tudo o que preciso e muito mais. Em vez de perder tempo adicionando sinos e apitos extras ao idioma, prefiro votar para melhorar a eficiência da funcionalidade existente. Atenciosamente, - Alexandre Kharlamov

Estou programando em vários jogos, programas tanto em casa como no trabalho há mais de 15 anos, mas só há cerca de 1 mês em Godot e posso dizer que sinto falta de vários recursos, que já estão abertos como solicitação de recurso em particular este recurso. ser capaz de aceitar e enviar números variáveis ​​de argumentos é algo que eu preciso com bastante frequência e está diminuindo a qualidade do código drasticamente se você tiver que contornar isso.

Um exemplo: => herança

class A
_init(arg0, arg1, arg2)

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

Agora imagine que você tem que mudar a lista de argumentos da classe A. Você terá que encontrar todas as classes que herdam esta classe, isso é perigoso. Apesar do fato de que não há argumentos nomeados, misturar a lista de argumentos é um problema por si só

Outro exemplo são os retornos de chamada, eu acho que isso ocorre sem código ...

Portanto, meu ponto é: godot ainda não faz tudo o que você precisa, ele apenas faz tudo o que é crucial (bem e, claro, um pouco mais :) ...). Porém, ainda não chegou a um ponto em que parar para adicionar recursos seria o melhor caso. No entanto, ter cuidado com o que adicionar é uma boa decisão.

Edit: Acabei de perceber que outro bom exemplo é o método Object.call () de Godots;)

DamKoVosh, por favor me diga, quantas linhas de código foi seu maior jogo? Cada vez que faço um jogo fico desapontado com a quantidade de codificação necessária. O grosso do trabalho é sempre o conteúdo, o teste, o equilíbrio da jogabilidade. Você está dizendo que reescrever é perigoso. Se nada mais, reescrever seu código o torna melhor em escrever interfaces e estruturas de dados preparadas para o futuro!

Conforme declarado na primeira mensagem neste tópico, toda a discussão é exatamente sobre o açúcar sintático para algo que já pode ser facilmente implementado usando um array em vez de implementar uma função variadic.

@alexkh

Conforme declarado na primeira mensagem neste tópico, toda a discussão é exatamente sobre o açúcar sintático para algo que já pode ser facilmente implementado usando um array em vez de implementar uma função variadic.

Como afirmado anteriormente por Geequlim , isso não é apenas um açúcar sintático, mas na verdade quebra a capacidade de substituir funções que usam varargs, como rpc , emit_signal , ... Acabei de encontrar esse problema quando Tentei mudar rpc com minhas necessidades.

Sim, é açúcar sintático. Porém, o fato de ser um açúcar sintático não significa que sejam bons ou ruins. Fluxo de controle como if , else e até mesmo funções são apenas açúcar em cima de GOTO também se você quiser. Isso não significa que você não os queira.

Às vezes, adicionar um pouco de açúcar sintático torna o código muito mais legível e vale a pena adicionar complexidade.

mas, na verdade, quebra a capacidade de substituir funções que usam varargs, como rpc, emit_signal

Curioso, que essas funções usam varargs e não arrays. ;-) Observe como a própria API Godot usa varargs em vários lugares? Provavelmente existe uma razão para isso.

Também curioso para saber quantas linguagens implementam funções variadic. Talvez eles sejam úteis mesmo que possam ser "facilmente implementados usando um array"?

Sinto muita falta deles no GDScript sempre que o uso, e esse é um dos motivos pelos quais prefiro o C #. Ou C ++. Ou Java. Ou Python. Ou vá.

Honestamente, acho que GDScript é a única linguagem em que trabalhei que não os possui. Além disso, talvez, Lua? Ah, eu verifiquei e eles parecem existir lá também. Não estou dizendo que devemos ter como objetivo adicionar tudo o que essas linguagens têm ao GDScript, mas se todas elas tiverem um recurso em comum, pode valer a pena.

Não posso julgar quanta complexidade isso adicionaria ao back-end GDScript e, portanto, não posso dizer muito sobre a compensação de complexidade, mas descartá-los porque são "apenas açúcar sintático" é errado, porque isso pode ser dito sobre muitas coisas.

Novamente, observe quantas coisas em Godot os usam.

Sim, é açúcar sintático. Porém, o fato de ser um açúcar sintático não significa que sejam bons ou ruins. Fluxo de controle como if , else e até mesmo funções são apenas açúcar em cima de GOTO também se você quiser. Isso não significa que você não os queira.

GOTO não substitui se porque é um salto incondicional. Você é mesmo um programador?

mas, na verdade, quebra a capacidade de substituir funções que usam varargs, como rpc, emit_signal

uma vez por ano, alguém em algum lugar desejará substituir a função rpc. Enquanto milhares de outras pessoas todos os dias desejam ver Godot 4 lançado.

Também curioso para saber quantas linguagens implementam funções variadic. Talvez eles sejam úteis mesmo que possam ser "facilmente implementados usando um array"?

Sinto muita falta deles no GDScript sempre que o uso, e esse é um dos motivos pelos quais prefiro o C #. Ou C ++. Ou Java. Ou Python. Ou vá.

C ++ não tem um tipo de array padrão que pode armazenar valores de tipos diferentes como o GDscript. Mesmo que C ++ suporte funções variadic, seu uso é desencorajado porque é de tipo inseguro. É um legado C, e em C em si era um açúcar sintático, porque printf era muito usado, especialmente para depuração - onde você deseja digitar rapidamente código temporário para gerar alguns dados. Foi totalmente justificado, porque foi usado o tempo todo - uma verdadeira economia de tempo! Mas você já escreveu sua própria função variável em C ou C ++?

Novamente, observe quantas coisas em Godot os usam.

Para saída de depuração - por todos os meios! Mas se print () não fosse variável, em vez de print ("Hello", "World), você teria que digitar print ([" Hello "," World "]) - nenhuma grande diferença ...

GOTO não substitui se porque é um salto incondicional

Bem, certo. Eu estava falando sobre saltos condicionais, é claro. O que ... você provavelmente poderia inferir. Ainda assim, o ponto permanece: nós construímos uma funcionalidade de nível superior no topo para sermos capazes de transmitir algumas coisas de forma mais limpa.

C ++ não tem um tipo de array padrão que pode armazenar valores de tipos diferentes como o GDscript.

Ok, argumente contra Python, Lua ou Go (ou qualquer host de outras linguagens), então eles têm essas e ainda têm funções variáveis.

Mas se print () não fosse variável, em vez de print ("Hello", "World), você teria que digitar print ([" Hello "," World "]) - nenhuma grande diferença

Claro, naquele caso de teste simples. Nos mais complexos, fica mais feio, especialmente quando você começa a ter dados de várias fontes e agora precisa colocá-los manualmente em um array primeiro. Eu concordo que não é uma grande perda; ainda assim, as funções variáveis ​​tornam o código mais limpo em alguns casos.

Mas...

Mas você já escreveu sua própria função variável em C ou C ++?

Você é mesmo um programador?

Como acima, não acho que você esteja argumentando de boa fé. Nesse caso, não estou mais interessado em falar com você, então ... não, apenas estou listado como um contribuidor do mecanismo porque sou um bom mascote, por favor, siga em frente.

GOTO não substitui se porque é um salto incondicional. Você é mesmo um programador?

Em sua maioria, as instruções condicionais, especialmente os loops, são apenas uma instrução de salto especializada, que é quase igual a uma instrução goto; em um sentido prático, a maioria das instruções de controle de sequência básicas que você encontra são uma extensão disso. Este é um argumento tolo para se apoiar (já que não constitui um argumento, apenas argumenta a semântica que é inútil) e essa segunda parte é desrespeitosa.

C ++ não tem um tipo de array padrão que pode armazenar valores de tipos diferentes como o GDscript. Mesmo que C ++ suporte funções variadic, seu uso é desencorajado porque é de tipo inseguro. É um legado C, e em C em si era um açúcar sintático, porque printf era muito usado, especialmente para depuração - onde você deseja digitar rapidamente código temporário para gerar alguns dados. Foi totalmente justificado, porque foi usado o tempo todo - uma verdadeira economia de tempo! Mas você já escreveu sua própria função variável em C ou C ++?

Embora C ++ não tenha um tipo de array padrão para varargs (ou arrays não digitados em geral), existem maneiras de lidar com isso há cerca de uma década (tecnicamente você poderia fazer isso antes mesmo de C ++ 11, no entanto, era muito macro e bastante hacky) e em segundo lugar com modelos varadic você pode pular completamente os problemas de digitação. Existem maneiras de lidar com varargs em C ++ usando modelos varadic. Aqueles que ainda acreditam em varargs em C ++ provavelmente estão começando do ponto errado nos dias de hoje.

Eu não ligo muito para a discussão pessoalmente (além de eu pessoalmente achar mais limpo e organizado ter algum tipo de argumentos varadic baseados em array em GDScript em vez de ficar no backend, acho que os recursos de linguagem devem ser implementados para a linguagem, não apenas sua execução, mas isso sou só eu), mas esses comentários precisavam ser corrigidos, e além de que você está agindo um tanto rude neste caso, você não fortalece seu ponto de vista nas mentes de seu público quando você responder negativamente à oposição que deve ser tratada objetivamente desta forma.

GOTO não substitui se porque é um salto incondicional. Você é mesmo um programador?

Em sua maioria, as instruções condicionais, especialmente os loops, são apenas uma instrução de salto especializada, que é quase igual a uma instrução goto; em um sentido prático, a maioria das instruções de controle de sequência básicas que você encontra são uma extensão disso. Este é um argumento tolo para se apoiar (já que não constitui um argumento, apenas argumenta a semântica que é inútil) e essa segunda parte é desrespeitosa.

K, eu desrespeito as pessoas que perdem meu tempo. Seu ponto era: por que não usar GOTO em vez de if, e eu disse que GOTO não substitui if. GOTO não é uma instrução condicional e se você deseja substituir a instrução condicional, apenas digite o que exatamente você deseja substituir. Algum exemplo já?

C ++ não tem um tipo de array padrão que pode armazenar valores de tipos diferentes como o GDscript. Mesmo que C ++ suporte funções variadic, seu uso é desencorajado porque é de tipo inseguro. É um legado C, e em C em si era um açúcar sintático, porque printf era muito usado, especialmente para depuração - onde você deseja digitar rapidamente código temporário para gerar alguns dados. Foi totalmente justificado, porque foi usado o tempo todo - uma verdadeira economia de tempo! Mas você já escreveu sua própria função variável em C ou C ++?

Embora C ++ não tenha um tipo de array padrão para varargs (ou arrays não digitados em geral), existem maneiras de lidar com isso há cerca de uma década (tecnicamente você poderia fazer isso antes mesmo de C ++ 11, no entanto, era muito macro e bastante hacky) e em segundo lugar com modelos varadic você pode pular completamente os problemas de digitação. Existem maneiras de lidar com varargs em C ++ usando modelos varadic. Aqueles que ainda acreditam em varargs em C ++ provavelmente estão começando do ponto errado nos dias de hoje.

Eu não ligo muito para a discussão pessoalmente (além de eu pessoalmente achar mais limpo e organizado ter algum tipo de argumentos varadic baseados em array em GDScript em vez de ficar no backend, acho que os recursos de linguagem devem ser implementados para a linguagem, não apenas sua execução, mas isso sou só eu), mas esses comentários precisavam ser corrigidos, e além de que você está agindo um tanto rude neste caso, você não fortalece seu ponto de vista nas mentes de seu público quando você responder negativamente à oposição que deve ser tratada objetivamente desta forma.

K, mas esse é exatamente o meu ponto: GDscript tem um tipo padrão que você pode iterar que pode conter diferentes tipos, então você não precisa mexer com todo o hackery necessário para fazer as funções variáveis ​​funcionarem em C ++, e é por isso , talvez, em C ++ modelos variadic sejam justificados.

K, eu desrespeito as pessoas que perdem meu tempo.

Então, vou deixar você perder seu tempo em outros projetos, pois agora você está impedido de interagir nos repositórios do @godotengine por 30 dias.

Temos um Código de Conduta que definitivamente não permite ser desrespeitoso com ninguém .

As propostas de recursos e melhorias para o Godot Engine estão agora sendo discutidas e revisadas em um rastreador de problemas dedicado às Propostas de Melhoria Godot (GIP) ( godotengine / godot-propostas ). O rastreador GIP tem um modelo de problema detalhado projetado para que as propostas incluam todas as informações relevantes para iniciar uma discussão produtiva e ajudar a comunidade a avaliar a validade da proposta para o mecanismo.

O rastreador principal ( godotengine / godot ) agora é exclusivamente dedicado a relatórios de bugs e solicitações de pull, permitindo que os contribuidores tenham um melhor foco no trabalho de correção de bugs. Portanto, agora estamos fechando todas as propostas de recursos mais antigas no rastreador de problemas principais.

Se você estiver interessado nesta proposta de recurso, abra uma nova proposta no rastreador GIP seguindo o modelo de problema fornecido (depois de verificar se ele ainda não existe). Certifique-se de mencionar este problema encerrado se incluir qualquer discussão relevante (que você também é incentivado a resumir na nova proposta). Desde já, obrigado!

Esta página foi útil?
0 / 5 - 0 avaliações