Últimamente me he sentido cada vez más frustrado porque en la mayoría de los lenguajes de programación modernos con los que he trabajado (C / C ++, C #, F #, Ruby, Python, JS y más) hay muy poco, si es que hay alguno, soporte de lenguaje para determinar qué una subrutina realmente servirá.
Considere el siguiente pseudocódigo simple:
var x = DoSomethingWith(y);
¿Cómo determino qué hará realmente la llamada a DoSomethingWith (y) ? ¿Mutará y , o devolverá una copia de y ? ¿Depende del estado global o local, o solo depende de y ? ¿Cambiará el estado global o local? ¿Cómo afecta el cierre el resultado de la llamada?
En todos los idiomas que he encontrado, casi ninguna de estas preguntas se puede responder simplemente mirando la firma de la subrutina, y casi nunca hay soporte en tiempo de compilación o tiempo de ejecución. Por lo general, la única forma es confiar en el autor de la API y esperar que la documentación y / o las convenciones de nomenclatura revelen lo que realmente hará la subrutina.
Mi pregunta es la siguiente: ¿Existe algún lenguaje hoy en día que haga distinciones simbólicas entre este tipo de escenarios y ponga restricciones de tiempo de compilación sobre qué código puede escribir realmente?
(Por supuesto, hay algo de apoyo para esto en la mayoría de los lenguajes modernos, como diferentes niveles de alcance y cierre, la separación entre código estático y de instancia, funciones lambda, etc.) Pero con demasiada frecuencia estos parecen entrar en conflicto entre sí. Por ejemplo, una función lambda generalmente será puramente funcional y simplemente devolverá un valor basado en parámetros de entrada, o mutará los parámetros de entrada de alguna manera, pero generalmente es posible acceder a variables estáticas desde una función lambda, que a su vez puede le da acceso a las variables de instancia, y luego todo se separa).