¿Cuál es la analogía más simple para explicar por qué las computadoras no pueden escribir automáticamente el código y el programa por sí mismas para el programador?

Qué pregunta tan cargada. Pueden! Los métodos son incipientes y aún no se escalan, pero existen. Este es un campo de investigación muy interesante que se ha vuelto significativamente más activo recientemente: la síntesis de programas .

Por supuesto, todavía necesita alguna forma de decirle a la computadora qué escribir. Hay algunos enfoques diferentes: trabajar en un dominio restringido o consultar interactivamente al usuario o incluso simplemente tomar algún tipo de especificación lógica.

Si solo apunta a un dominio muy específico, puede generar automáticamente programas útiles sin mucha información. Un gran ejemplo es en el campo de la optimización de compiladores: escribir las diversas reglas de optimización de mirilla es una tarea difícil que generalmente realizan los expertos. Pero también está muy bien definido: solo tiene que escribir reglas que toman algún ensamblaje como entrada y asignarlo a un ensamblaje más eficiente que haga lo mismo. ¡Oye, resulta que puedes hacer que una computadora escriba estas reglas por ti! Echa un vistazo a la generación automática de superópticos de mirilla para un sistema que hace exactamente esto. Puede tardar mucho tiempo en ejecutarse, digamos semanas de tiempo de procesador, pero también ofrece muchas más reglas de optimización que los humanos. ¡Esto se traduce en mejoras reales en el optimizador generado sobre uno escrito por expertos! Incluso han utilizado este mismo enfoque para la traducción binaria: Traducción binaria usando superepéptidos de mirilla .

Si desea un sistema más general para la escritura automática de algoritmos, puede solicitar interactivamente a un usuario entradas y salidas de muestra. Esto se llama “programación por ejemplo”. Un gran ejemplo es Flash Fill, que pasó de ser un proyecto de investigación de MSR a ser una característica en Excel 2013. Esto genera y ejecuta programas de manipulación de cadenas basados ​​en datos en una hoja de cálculo. A menudo, solo uno o dos ejemplos son suficientes para generar un programa correcto; sin embargo, el sistema también puede solicitar al usuario entradas adicionales. Incluso lo hace de manera inteligente: utiliza algo de aprendizaje automático para adivinar qué entradas tienen más probabilidades de causar problemas y le pregunta al usuario sobre esas entradas. Ahora, en lugar de escribir este código de manipulación de cadenas manualmente, puede generarlo haciendo algunos ejemplos a mano. El mismo equipo de MSR también ha utilizado la síntesis del programa para muchas otras cosas interesantes.

Los dos enfoques anteriores pueden escalar relativamente bien y requieren una entrada limitada del usuario; en ambos casos, esto funciona porque apuntan a dominios muy especializados. Sin embargo, también hay enfoques más generales. Un ejemplo es Program Synthesis by Sketching , un enfoque que utiliza técnicas de síntesis para llenar los “agujeros” en los programas. Escribes un resumen de tu programa, pero dejas fragmentos difíciles para el sintetizador. En la práctica, también debe especificar lo que está buscando, que puede ser un conjunto de casos de prueba para pasar o un algoritmo escrito ingenuamente. Por ejemplo, supongamos que desea escribir una transposición matricial eficiente utilizando la instrucción SIMD. Primero, escribe una especificación no optimizada:

  int [16] transposición (int [16] M) {
   int [16] T = 0;
   para (int i = 0; i <4; i ++)
     para (int j = 0; j <4; j ++)
       T [4 * i + j] = M [4 * j + i]
   volver T
 }

A continuación, descubres la estructura aproximada del código. En particular, la idea es que podemos usar la instrucción shufps para mezclar primero la matriz de entrada en una matriz temporal S y barajar S en T. La instrucción shufps toma tres argumentos: dos vectores de cuatro números y un vector de bits que controlan cómo se barajan. . Resolver estos argumentos es muy difícil, ¡pero felizmente el sintetizador puede hacerlo por usted! Simplemente escriba la estructura general del código, dejando (??) para agujeros:

  int [16] transpose_simd (int [16] M) implementa la transposición {
   int [16] S = 0, T = 0; 
   repetir (??) S [?? :: 4] = shufps (M [?? :: 4], M [?? :: 4], ??);
   repetir (??) T [?? :: 4] = shufps (S [?? :: 4], S [?? :: 4], ??);
   devolver T;
 }

Aquí repeat es una directiva de sintetizador que le dice que copie la línea varias veces en lugar de usar un bucle; el ?? puede tomar diferentes valores cada vez que se copia la línea.

El sintetizador luego escupe el código correcto, lo que habría tomado una eternidad para escribir a mano:

  int [16] transpose_simd (int [16] M) implementa la transposición {
   int [16] = S = 0, T = 0; 
   S [4 :: 4] = shufps (M [6 :: 4], M [2 :: 4], 11001000b);
   S [0 :: 4] = shufps (M [11 :: 4], M [6 :: 4], 10010110b);
   S [12 :: 4] = shufps (M [0 :: 4], M [2 :: 4], 10001101b);
   S [8 :: 4] = shufps (M [8 :: 4], M [12 :: 4], 11010111b);
   T [4 :: 4] = shufps (M [11 :: 4], M [1 :: 4], 10111100b);
   T [12 :: 4] = shufps (M [3 :: 4], M [8 :: 4], 11000011b);
   T [8 :: 4] = shufps (M [4 :: 4], M [9 :: 4], 11100010b);
   T [0 :: 4] = shufps (M [12 :: 4], M [0 :: 4], 10110100b);
   devolver T;
 }

Tomé este ejemplo de las diapositivas (http://www.cs.berkeley.edu/~bodi…) en un curso para programar síntesis que vale la pena leer.

Los sintetizadores pueden incluso crear sus propios algoritmos para problemas. Por ejemplo, comenzando con la función para la multiplicación de Montgomery de OpenSSL, un superoptimizador llamado STOKE escribió un programa x86_64 1.6 veces más rápido que GCC con -O3, ¡un poco más rápido que el ensamblaje escrito por expertos y usando un algoritmo diferente al de la entrada!

Esto es solo una muestra de herramientas de síntesis. Ya existen muchos y cada día salen más. En este momento, tienen un alcance limitado o solo pueden sintetizar pequeños programas, pero sus capacidades se están expandiendo rápidamente. Es un campo bastante emocionante.

Debido a que un programa no tiene ningún propósito, no tiene voluntad propia, no hay problema para resolver, no es necesario.

Imagina que eres un escritor experimentado. Si tiene suficiente experiencia y tiene la mentalidad para ese tipo de cosas, incluso puede escribir un manual que explique cómo escribir un libro …

Ahora, ¿podrán sus lectores escribir un libro real simplemente siguiendo su manual? Realmente, sus lectores tendrán que agregar algunos aportes propios. Al menos tendrían que elegir de qué tratará su libro.

Y cualquier manual que sea suficiente por sí solo para escribir tal libro solo permitiría escribir algunos libros, simplemente seleccionando y pegando párrafos existentes, de un conjunto muy restrictivo de todos los libros posibles. Sin embargo, si el manual es muy grande, podría dar algunos resultados interesantes: no piense en las novelas, sino, por ejemplo, en los contratos legales estándar.

Eso es básicamente lo que sucedió durante años con las computadoras y el software. Los programas que deben escribirse y los que ya existen cambian con el tiempo. Los programadores pueden escribir software cada vez más complejo escribiendo cada vez menos código utilizando material extenso (incrustado en lenguajes de programación, bibliotecas estándar, generadores de aplicaciones, etc.) pero los usuarios finales aún tienen que proporcionar su entrada.

Al final, el programador es el único que sabe lo que quiere que haga un programa determinado. Si esto es algo habitual como escribir un sitio web simple, probablemente ya esté disponible y unos pocos clics podrían ser suficientes. Si es algo nuevo, será más difícil.

Las computadoras han estado escribiendo código y programándose desde 1952. Se llama un “compilador”. Esencialmente, usando un compilador, el humano le dice al compilador qué quiere que haga la computadora y el compilador genera un programa para hacerlo. Esa es una programación de computadora en sí misma.

Pero, dices … ¡escribir instrucciones para el compilador todavía está programando! El hecho de que no esté codificando en lenguaje ensamblador no significa que no esté programando. Sí, tienes razón, estás programando en un nivel más alto de abstracción. Los primeros lenguajes de programación resumieron la necesidad de conocer las instrucciones de la máquina, pero no resumieron la arquitectura de hardware del sistema. El programador necesitaba conocer la arquitectura del hardware subyacente. Luego vinieron los sistemas operativos que extrajeron el hardware, lo que facilitó el trabajo. Ahora el programador necesita comprender el sistema operativo y comprender el funcionamiento básico del hardware. Luego vinieron las máquinas virtuales que abstrajeron el sistema operativo. Ahora, el programador necesita comprender los componentes de la VM

Entonces, seguimos encontrándonos con este problema de que el programador necesita saber algo sobre la tecnología que ejecuta el software. No puede ser una persona de negocios pura. Ella no puede simplemente decir ” Crear una base de datos que almacene la información del Cliente con estos campos. Ahora, dame una página web que pueda usar para manipular los datos del cliente”. Ah, pero espera, ¿qué es “base de datos” y “página web”? Es tecnología, ¿verdad? Puede crear un intérprete que se ejecute en una máquina virtual que escuche los comandos y los programas generados en función del comando. Sin embargo, esos comandos tendrán que estar vinculados a la tecnología. Todavía está programando a un nivel muy alto de abstracción. Puedes seguir abstrayendo más y más. No puedes alejarte del hecho de que no puedes abstraerte sabiendo cómo deben hacerse las cosas. ¿Porqué es eso?

¿Por qué no pueden las computadoras descubrir qué es lo que hay que hacer ya? Quiero decir que tu jefe no te dice “Crea una base de datos que almacene la información del Cliente con estos campos. Ahora, dame una página web que pueda usar para manipular los datos del cliente”, ¿verdad? Cada pieza de software comienza con un problema que debe resolverse: tenemos problemas para organizar la información de nuestros clientes. Quiero decir que está por todo el lugar. Está en archivos físicos … está en la cabeza de las personas … rolodexes … diablos, parte está en notas post-it. Es muy difícil encontrar algo. Necesitamos algo que nos ayude a encontrar información del cliente rápidamente.

Pocas cosas a tener en cuenta:

Las declaraciones de problemas no le dicen qué hacer. Las declaraciones de problemas le dicen lo que necesitan.
Y ahí es donde entra el ser humano. Los humanos son muuuuchas … como un gazzilion veces mejor que las computadoras para resolver problemas. Es mucho más fácil para un humano decir Ahh, todo lo que necesitamos es una base de datos de Clientes y una página web para administrar esa información. ¡Hecho! Las computadoras no pueden hacer eso. No pueden dar estos saltos que van desde la declaración del problema hasta la posible solución. Un programador podría decir algo así intuitivamente. Sin siquiera pensarlo.

Por supuesto, las computadoras están mejorando en esto todos los días. Con todo lo de ML que está de moda hoy en día, las computadoras están mejorando en la búsqueda de relaciones entre la información sin que se les diga exactamente cómo hacerlo. ¡Eso es genial! Sin embargo, no están en el punto donde pueden resolver problemas de forma independiente

La comunicación humana es ruidosa
Mira por el ruido en esta declaración (es decir, lo inventé para que fuera ruidoso … pero no está muy lejos de cómo exactamente las personas expresan sus necesidades)

Tenemos problemas para organizar la información de nuestros clientes. Quiero decir que está por todo el lugar. Está en archivos físicos … está en la cabeza de las personas … rolodexes … diablos, parte está en notas post-it. Es muy difícil encontrar algo. Necesitamos algo que nos ayude a encontrar información del cliente rápidamente.

En primer lugar, no te dice qué significa cliente. Es el nombre? nombre y dirección? nombre / dirección y número de teléfono? Nombre / dirección / número de teléfono y tamaño de la cintura? En segundo lugar, tiene esta información extraña sobre dónde está la información en este momento. Dependiendo de la extensión de la solución, el lugar donde se almacena la información en este momento puede ser irrelevante. Por último, es ambiguo. No le dice si necesitan solo una forma de organizar la información o si necesitan ayuda para transferir la información.

Los humanos son mucho mejores para lidiar con el ruido. Los humanos son buenos para hacer preguntas. Cuando alguien les da información, pueden descubrir rápidamente qué información falta y formular nuevas preguntas. Los humanos pueden llevar a cabo un diálogo. Las computadoras no pueden.

Escaneo de computador.

Al igual que Google sugiere a menudo puede darle las respuestas correctas a una consulta con un error tipográfico, los kits de herramientas de desarrollo de software pronto podrán darle soluciones listas para enchufar para errores de compilación y pruebas unitarias fallidas.

Bueno, relativamente pronto. Cinco diez años.

Sin mencionar los algoritmos genéticos, en algunos idiomas el código de escritura automática ya está sucediendo.

¿Cómo le dirías a la computadora para qué quieres que escriba sus propios programas?

Aún necesitaría darle algún tipo de instrucciones precisas, no ambiguas y estructuradas sobre lo que desea, porque la computadora solo puede seguir instrucciones, no tomar decisiones. (Decisiones como en juicios, no decisiones como en pruebas de condición).

Una forma precisa, no ambigua y estructurada de dar instrucciones a una computadora me parece una definición de lenguaje de programación. Los lenguajes de programación pueden tener diferentes niveles de abstracción, pero incluso si está usando algo realmente muy abstracto como Applescript, que le permite decirle literalmente a la computadora algo como “Si aparecen imágenes en formato JPG en esta carpeta, conviértalas a PNG y moverlos a esa carpeta “, todavía le está dando un conjunto preciso e inequívoco de instrucciones para que siga.

¡Nunca puede escapar al hecho de que necesita decirle a la computadora, sin ambigüedades, lo que quiere hacer!

Intención.

Una computadora no tiene intenciones. Solo puede heredar las intenciones del programador.

Las otras respuestas sobre los programas que escriben programas son buenas, excepto cómo escriben sus programas, cómo pretenden escribir sus programas, aún deben heredarse del programador. La intención es la esencia del libre albedrío y de estar vivo, y cómo se genera nueva inteligencia.

Sin intención, una computadora no puede generar su propia inteligencia.

¿Quién escribe el código? Programadores. ¿Cómo escriben el código? Intencionalmente, y según su mejor entendimiento. Nunca ha sido de otra manera. Podemos escribir código que escriba más código, pero no podemos escribir código que sea intencional por sí solo.

Una analogía simple sería un niño que solo puede hacer lo que se le dice. Pero un niño puede aprender. Una computadora solo puede grabar. Incluso con IA, las computadoras solo graban. No pueden aprender como nosotros, porque incluso nosotros no entendemos completamente lo que facilita el aprendizaje. Grabar es fácil y es una copia de seguridad en comparación con el aprendizaje. Ni siquiera es remotamente un sustituto.

Tal como están las cosas, todo el código de la computadora hereda las intenciones del programador. El programa se comporta como el programador desea que se comporte. Una computadora por sí sola no tiene intenciones. No sabe qué hacer consigo mismo. Es tan simple como eso.

Pero aquí es donde comienza el verdadero misterio. ¿Qué es la intención? Sabemos muy poco acerca de nuestra propia intención. Solo pensarlo puede ser confuso, porque desde que tenemos memoria, siempre hemos sido intencionales y hemos tenido nuestra independencia y libertad intelectual. El hambre y el deseo de ser feliz son simples deseos que tenemos. La autoconservación y el miedo a la muerte también son simples impulsores de nuestras propias intenciones. ¿Pero en qué momento las personas construyen intencionalmente aplicaciones para teléfonos inteligentes para ayudarlas con una tarea? ¿Y quién fue el primer ser que hizo algo intencionalmente? La conclusión es la siguiente:

Ni siquiera entendemos qué hace que las personas escriban código. Ni siquiera entendemos nuestras propias intenciones.

Con esta comprensión vendrá nuestra capacidad de diseñar una computadora que pueda. Pero hasta entonces, debemos seguir estudiando, seguir buscando y seguir investigando. Y la respuesta no está en una computadora. Está en nuestra propia conciencia y en nuestra arquitectura biológica. Todo esto me parece increíblemente fascinante.

Porque más del 50% de la ingeniería de software se trata de comunicaciones (con personas reales). Se trata de comprender los requisitos, evaluar posibles enfoques arquitectónicos, diseñar y … algo de codificación. La codificación solo ocurre como parte de todas estas tareas diferentes y no puede ocurrir aisladamente de estas otras tareas.

Las computadoras, por sí solas, no pueden realizar estas tareas e incluso si pudieran programar, el programador necesitaría conciliar lo que ha aprendido a lo largo de su recopilación de información y la arquitectura que desea implementar. Eso requeriría algunos diálogos bastante desagradables entre el programador y la computadora que es posible, pero solo si ambos usan un lenguaje común. Por cierto, existe un lenguaje tan común que se llama C ++, java, etc.

Analogía : por qué las computadoras no podían jugar ajedrez automáticamente (e ir) a nivel humano o superior.

Todas las razones enumeradas en otras respuestas se dieron de manera diversa para el ajedrez, y especialmente ir, donde la búsqueda directa no tiene remedio. Sin embargo, las computadoras ahora juegan al ajedrez mucho mejor que las personas, y la computadora está llegando allí.

Larga historia corta: puede.

Alguien solo tiene que escribir el programa que le dice cómo. Resulta que es tan difícil como escribir el programa usted mismo. Los programadores son flojos, por lo que simplemente eligen la opción más familiar.

Sin embargo, de vez en cuando, alguien viene y piensa que tiene una mejor manera de explicar claramente a la computadora qué escribir. A veces, los escriben y los reparten. Si son lo suficientemente útiles, incluso los llamamos lenguajes de programación.

Si bien me gustan las otras respuestas que señalan que las computadoras realmente pueden hacer esto (especialmente la de Tikhon Jelvis), esa no es la pregunta. ¿La analogía más simple?

Un automóvil tampoco lo llevará a su destino automáticamente.

Incluso si tiene satnav, aún tendrá que ingresar su destino. Incluso si tiene control de crucero, guía de carril, control de crucero adaptativo, etc. Todavía necesita un conductor.

Podemos hacer grandes esfuerzos debatiendo que hay sistemas experimentales (los autos autónomos de Google, etc.), o autos muy elegantes y caros (como el nuevo Mercedes S), que pueden conducir solos sin que alguien tenga que ser el conductor.

Pero estos están lejos de la norma. Y todavía tiene que decirles a dónde ir o es absolutamente inútil como medio de transporte.

Ni siquiera necesito una analogía. La industria revisa la idea cada diez o quince años (de hecho, estamos atrasados ​​por una bala de plata), y el resultado final es siempre el mismo: el software puede generar otro software, pero aún necesita que alguien le explique al generador qué debe hacer. generar .

La especificación debe ser detallada y formal, lo que … ¡es un programa!

Esto es inevitable, no porque los humanos sean especiales (aunque nosotros también podríamos serlo), sino porque el software se crea al servicio de las personas, por lo que esas personas necesitan describir sus necesidades. Podemos cambiar cómo pueden hacerlo directamente (es decir, si cada uno de nosotros es un programador o solo unas pocas personas que son contratadas para hacer el trabajo sucio por nosotros) y podemos cambiar la dificultad del proceso, pero podemos ‘ t eliminarlos del proceso.

Menciona los compiladores excluyentes, pero ellos (junto con los marcos) son exactamente de lo que se trata la pregunta. El lenguaje de máquina / ensamblaje es doloroso, por lo que escribimos software para generarlo para usted, si lo explica así. C es una molestia, por lo que escribimos un software que le permite organizar sus pensamientos como una simulación de objetos. Java es una molestia, por lo que eliminamos la sintaxis. Creamos bibliotecas y marcos para evitar repetir el trabajo, y codificamos enfoques comunes para la resolución de problemas en lenguajes y entornos.

Tan lejos como lo extiendes, todavía hay alguien que le dice a la computadora lo que hay que hacer. El trabajo de esa persona puede diferir del mío tanto como el mío difiere del de Alan Turing (y de cómo el suyo difería del de Ada Lovelace), en los detalles, y cada generación facilita el trabajo en la próxima, pero es el mismo trabajo en el núcleo. Todavía está decidiendo qué aspectos de un problema son importantes y cómo presentar los resultados de una manera que facilite la vida de alguien.

Incluso si imagina un futuro en el que todos los programas posibles ya se han escrito (por lo que, literalmente, no hay más programación que hacer), aún necesita a alguien que sepa cómo encontrar el programa adecuado para resolver el problema. Las habilidades de esa persona son básicamente las de un programador.

Al igual que un automóvil no puede conducir solo. Necesita un conductor. Un automóvil es una máquina diseñada para responder. Solo comienza cuando alguien gira la llave en el encendido. Solo se mueve cuando presiona el acelerador y así sucesivamente.
Del mismo modo, una computadora está diseñada para decodificar instrucciones en el nivel más básico. Estas instrucciones están escritas por programadores. Controlamos lo que computa. A menos que de alguna manera creemos un programa de pensamiento propio y lo carguemos para su ejecución, una computadora no podrá ‘programar’.

Por la misma razón que tu gato no puede. Las computadoras aún no son lo suficientemente inteligentes.

Porque las computadoras no pueden leer las mentes.

Un programa de computadora es como una relación definida en conjuntos de entrada y salida. Hay (solo una suposición) un número infinito de posibles relaciones y el trabajo del programador es seleccionar la (y solo una) que sea “interesante”. Incluso si tiene una “computadora” para “programarse a sí misma”, entonces no podría seleccionar el programa que le interesa.

Si tengo una tienda, ¿por qué no puedo ser mi propio cliente? Entonces podría garantizar que obtendría muchas ventas.

Esta es la clave de la verdadera IA y puede caracterizarse como aprendizaje.

Yo diría que la falta de intención no es un problema en absoluto. Podemos proporcionar una plantilla para la operación.

El problema es que es demasiado complejo y simplemente no hemos llegado tan lejos todavía.

Imagina jugar Call Of Duty en una calculadora de bolsillo.

Puede, si el programador le dice cómo hacerlo. Puede buscar “metaprogramación”.

Es la misma razón por la que un martillo no construye automáticamente una mesa sin el carpintero.