Pergunta

Por que algumas línguas diferenciar entre métodos que retornam um valor e métodos que não fazer?

i. em Oracle PL / SQL, onde a principal diferença entre uma função e um procedimento é que a função deve retornar um valor, eo procedimento não deve.

Da mesma forma para idiomas que não, porque não?


EDIT: Eu encontrei uma pergunta relacionada que as pessoas de juros poder ler esta pergunta:

Foi útil?

Solução

Por causa nas concepções originais da teoria Ciência da Computação e prática, funções e sub-rotinas tinha praticamente nada a ver um com o outro.

Fortran é geralmente creditado como o primeiro idioma que implementou ambos e demonstrou as distinções. (Início LISP teve um papel um tanto opondo-se nisto também, mas teve pouco fora impacto da academia).

sequência das tradições de matemática (CS que ainda era parte no 60) funciona apenas foram observados quanto a encapsulação de cálculos matemáticos parametrizadas destina apenas a devolver um valor para uma maior expressão. Que você poderia chamá-lo de "nu" (F = Azimute (segundos)) foi apenas um caso de uso trivial.

sub-rotinas, por outro lado, foram vistos como uma forma de nomear um grupo de instruções destinadas a ter algum efeito. Parâmetros foram um enorme impulso à sua usabilidade e a única razão que eles foram autorizados a retornar valores dos parâmetros modificados era para que eles pudessem relatar seu status sem ter que depender de variáveis ??globais.

Assim, eles realmente não tinha nenhuma conexão conceitual, diferente de encapsulamento e parâmetros.

A verdadeira questão, é: "Como é que tantos desenvolvedores vêm para vê-los como o mesmo"

E a resposta para isso é C.

Quando K + R originalmente concebido seu alto nível macro assembler linguagem tipo para os PDP-11 (pode ter começado no PDP-8?), Eles não tinham ilusões de independência de hardware. Praticamente todos os recursos "único" da língua era um reflexo da linguagem de máquina PDP e arquitetura (ver i ++ e --Eu). Uma delas foi a realização das funções e sub-rotinas poderia ser (e sempre foi) implementada de forma idêntica na PDP, exceto que o chamador simplesmente ignorou o valor de retorno (em R0 [, R1]) para sub-rotinas.

Assim nasceu o ponteiro nulo, e depois da linguagem C havia tomado todo o mundo da programação, a percepção equivocada de que este artefato de implementação HW / OS (embora verdadeiro em quase todas as plataformas subsequente) foi a mesma que a semântica da linguagem.

Outras dicas

Em um ambiente puro ou digitado efeito existe um mundo de diferença, porque, obviamente, métodos que "não retornam nada" só são úteis para seus efeitos colaterais.

Isso é análogo à distinção entre expressões e declarações, que pode declutter uma linguagem e eliminar uma classe de programas geralmente-equivocadas (que, é claro, é por isso que C não o faz;)).

Para dar um pequeno exemplo, quando você distinguir claramente entre expressões e declarações, if(x = 3), ao contrário de if(x == 3) é sintaticamente incorreto (para usar uma declaração onde uma expressão era esperada) e não apenas um erro de tipo (para usar um inteiro onde um booleano era esperado). Isto tem a vantagem de também não permitindo if(x = true) que seria permitido por uma regra baseada em tipo num contexto em que as atribuições são expressões que têm o valor de seu operando direito.

Em uma linguagem que encapsula efeitos com mônadas, a distinção importante se torna a única entre:

  • funções que () retorno que são funções puras e só pode retornar um valor vazio inútil chamado () ou divergem
  • funções que IO () retorno (ou unidade de alguma outra mônada), que são funções sem "resultado", exceto efeitos no IO (ou qualquer) mônada

Desculpe-me responder a uma pergunta de dois anos, especialmente com algo único para a minha própria língua Felix http: // felix-lang. org mas aqui vai de qualquer forma:)

Em Felix, funções e procedimentos são diferentes fundamental e não é apenas que os procedimentos têm efeitos colaterais e são chamados em declarações, enquanto que as funções não têm efeitos colaterais e são usados ??em expressões (porque Felix também tem geradores que são funções com efeitos colaterais ..:)

Não, o modelo de execução é fundamentalmente diferente, principalmente por razões de desempenho, mas não inteiramente. O modelo é:

  • Funções colocar seu endereço de retorno na pilha da máquina, eo valor de retorno também.
  • Procedimentos usar uma lista ligada na pilha. código de procedimento é plana, ela não usa a pilha da máquina.

Este é normalmente ineficiente, então por que fazê-lo? A resposta é: procedimento Felix são todos potencialmente co-rotinas (fibras). Eles podem alternar o controlo para outro procedimento através do acesso a um canal. Isso faz com que uma troca de controle.

  • Por motivos de desempenho copiar a pilha de máquina em troca de controle não é uma opção.
  • Por razões de gestão de memória trocando ponteiros de pilha não é uma opção.

O sistema operacional normalmente swaps pilha ponteiros para tópicos, que é razoavelmente rápido, mas tem um problema fundamental em máquinas endereço linear: você tem que limitar o tamanho máximo da pilha para um ridiculamente pequeno valor, ou limitar o número de threads a um ridiculamente pequeno valor. Em uma máquina de 32 bits, não há espaço de endereço suficiente para sequer contemplar essa solução. Em uma máquina de 64 bits, troca de pilha tem mais potencial, mas é claro utilizador exige sempre crescer para hardware outstrip 3 dias depois é liberado ..:)

Felix apenas troca de um único ponteiro para as pilhas baseada em heap, então trocas de contexto são incrivelmente rápidas e muito pouco espaço de endereço é desperdiçado. É claro que o custo é de alocações de heap em chamadas de procedimento.

No compilador, um monte da arquitetura do modelo teórico é otimizado afastado em um "como se" base, o desempenho e implementação de modo real pode ser bastante diferente do modelo teórico, desde que o compilador pode provar que você pode 't dizer a diferença .. além de ser negada a oportunidade de fazer uma xícara de café com lazer:)

Então aqui, você tem uma resposta diferente a respeito de porque as funções e procedimentos podem ser tratados de forma diferente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top