uqbar-project / wollok

Wollok Programming Language
GNU General Public License v3.0
60 stars 16 forks source link

Algo muy sencillo: como se escribe un while? #1768

Open Nykros opened 5 years ago

Nykros commented 5 years ago

Donde se documentan las estructuras de control del lenguaje?

PalumboN commented 5 years ago

Je, no hay while. Creo que la única estructura de control que existe es el if.

Nykros commented 5 years ago

Tienen alguna buena razón para ello?

PalumboN commented 5 years ago

Sí, hay razones pedagógicas para incentivar el uso de objetos y mensajes. Pero siempre se pueden discutir :)

Nykros commented 5 years ago

Esas razones están escritas en alguna parte?

npasserini commented 5 years ago

Hola @Nykros te agradezco mucho tus comentarios. El por qué no tenemos una construcción de repetición condicional (a.k.a. while) tiene una historia larga y que aún no está terminada.

Inicialmente Wollok retoma muchas ideas de lenguajes como Smalltalk, que no tienen estructuras de control. Si bien Wollok rompe en parte con esa tradición e incorpora algunas, siguen siendo muy poquitas, básicamente if, try y sus complementos. Podés encontrar más información sobre la sintaxis de Wollok en https://www.wollok.org/documentacion/conceptos/

Las motivaciones para esto se pueden buscar en la literatura más tradicional de POO, Smalltalk, Pharo, Newspeak, etc; no recuerdo en este momento un escrito de esas características que haya surgido del grupo de docentes que impulsamos Wollok, son ideas que nos preexisten largamente y que nosotros humildemente incorporamos y adaptamos a nuestra visión de la enseñanza.

Al comenzar el desarrollo de Wollok se charló bastante sobre incorporar la repetición condicional. Sin embargo había varias visiones sobre cómo hacerlo y por ese motivo se fue postergando. No descarto que se agregue en un futuro más o menos cercano.

Tal vez vale la pena notar que la experiencia de 5 años por ahora nos fue llevando por otros caminos, priorizar otras cosas. Decenas de docentes y miles de estudiantes han usado Wollok y pocas veces surgió esta necesidad y por eso nuestras propuestas al respecto por ahora siguen en el backlog. Eso me lleva a pensar que tal vez para el objetivo específico del lenguaje Wollok, la repetición condicional no es un elemento central: Wollok no es un lenguaje industrial, ni de propósito general; tiene un objetivo bien concreto que es introducir la programación con objetos.

Sé que hay gente que lo ha utilizado con otros objetivos, desconozco si alguien lo utilizó para enseñar algoritmia. Eso de ninguna manera quiere decir que el equipo detrás de Wollok no considere valiosos esos conocimientos, simplemente no son el foco de las materias que dictamos. Hasta donde llega mi conocimiento, en todos los espacios donde se utiliza Wollok, los estudiantes tienen más materias de programación que se ocupan específicamente del conocimiento algorítmico.

¿Vos sos docente de programación? ¿Te interesaría utilizar Wollok en un curso focalizado en la algoritmia? Nos gustaría conocer más de tu necesidad y hacer lo que esté dentro de nuestras posibilidades para extender nuestras herramientas para y darle soporte al uso que le querés dar.

Quedamos a la espera de más contribuciones. Muchas gracias y saludos.

fdodino commented 5 years ago

Por el momento no lo necesitamos, y creo que esa es una razón de peso, si te interesa sumarte a la lista de discusión del lenguaje sos más que bienvenido @Nykros . Mi voto es por cerrar el issue.

Nykros commented 5 years ago

En mi opinión, el while es parte de la caja de herramientas que debería estar disponible en el lenguaje para aumentar su expresividad. No es un cuestión de necesidad, porque sino cualquier lenguaje Turing-complete daría lo mismo. Es una cuestión utilizar la herramienta adecuada para resolver el problema en manos, y muchas veces simular un while con objetos que se envian mensajes a si mismo no es lo mejor.

Respeto vuestras opiniones y agradezco el esfuerzo que ponen este proyecto.

clombardi commented 5 years ago

Bueno, me voy a atrever a reabrirlo. Como en UNAHur hay mucha disparidad de nivel, los rapiditos se aburren y se van, y después aparecen clase sí clase no, justo se pierden "la" explicación, y la cagan. Para mitigar este fenómeno, estoy agregando ítems desafío en varios ejercicios. Algunos van para el lado de la algoritmia, y lo bien que vendría un while ahí. En una mirada un poco más global, si quisiéramos que más gente use Wollok, no todos van a compartir nuestra visión de "objetos 3 algoritmia 0". En particular, si alguien se animara a usar objetos desde la primer materia de programación, basándose en Wollok durante todo el primer año, algo de algoritmia tiene que poner. Si me dicen que hay mil prioridades antes, OK. Pero creo que con la decisión de no incluir while, por decirlo rápido, perdemos clientela. Si Wollok tuviera while, y une alumne me pregunta cómo es el while cuando arrancamos con colecciones, respondería que no importa y que no vale usarlo hasta nuevo aviso.

fdodino commented 5 years ago

Yo me opongo fuertemente.

Tengo dos motivos:

Después, sobre el tema de la clientela, seguramente habrá gente que pensará que no está bueno, pero no creo que Wollok compita contra Pascal o C, o es una batalla que prefiero no dar.

En fin, dejo mi -1 fuerte por acá.

clombardi commented 5 years ago

Respecto de los ejemplos, para al menos los dos que surgieron la semana pasada en UNAHur se me ocurrieron soluciones elegantes a partir del rango de índices. Uno es saber si una lista está en orden creciente, se puede hacer así (creo):

lista.size() <= 1 or (1..lista.size() - 1).all({ n => lista[n] > lista[n-1])

El otro es si una lista es intercalada (o sea sus elementos están intercalados entre los del tipo A y los del tipo B). Vamos:

cosnt hayUnoDeCada = { (e1, e2) => (e1.esUnA() and e2.esUnB()) or (e1.esUnB() and e2.esUnA()) }
lista.size() <= 1 or (1..lista.size() - 1).all({ n => hayUnoDeCada.apply(lista[n], lista[n-1]))

Listo, soy un hombre feliz.

Obsérvese que evito responder a los argumentos de Fer, con varios estoy en desacuerdo pero así es la vida.

npasserini commented 5 years ago

Uno de los motivos que llevaron a la postergación del while fue la intención de buscar soluciones más objetosas. La fácil es poner el whileTrue a los bloques, a la smalltak. Expresivamente tiene la misma potencia que el while pero no deja de ser un mensaje. Carlos/Fer, qué les parecería esta solución?

Una que me gustaría aún más es incorporar un objeto stream y a partir de ahí tener streams infinitos. El stream podría parecerse a un iterator de Java, pero con un iterador interno (aka foreach, pero podría extenderse a más métodos de los que nos gustan de las colecciones).

Tiro una punta inicial como para seguir imaginando:

Iterar una colección sería: method iterador(lista) { var index = 0 const stream = new Stream(hasNext = { index < lista.size() }, next = { index += 1; lista.get(index-1) }) }

luego self.iterador(lista).forEach { element => lo que vos quieras }

Básicamente jugando con hasNext y next podés hacer lo que vos quieras.

Incluso, en esos ejemplos, conviene más armar otro tipo de stream:

method pares(lista) { var index = 0 const stream = new Stream(hasNext = { index < lista.size() - 1 }, next = { index += 1; lista.get(index-2) -> lista.get(index-1) }) }

Y luego

self.pares(lista).all { par => par.x() < par.y() }

(En realidad otra opción podría ser agregar la función pares a la lista.)

En realidad todas estas operaciones con listas se pueden hacer en base a fold. Pero bueno, el stream permite trabajar con whiles que no tengan un conjunto predefinido.

const streamInfinito = new Stream(hasNext = { true }) (podría ponerle el next pero tal vez más fácil si funciona con un default)

de hecho, esto último podría hacer el mensaje whileTrue en bloque y por lo tanto esta solución en realidad engloba a la primera. El stream es una idea poderosa, al punto que podemos pensar todas nuestras colecciones actuales como subclases de stream.

El mié., 25 de sep. de 2019 a la(s) 22:32, Carlos Lombardi ( notifications@github.com) escribió:

Respecto de los ejemplos, para al menos los dos que surgieron la semana pasada en UNAHur se me ocurrieron soluciones elegantes a partir del rango de índices. Uno es saber si una lista está en orden creciente, se puede hacer así (creo):

lista.size() <= 1 or (1..lista.size() - 1).all({ n => lista[n] > lista[n-1])

El otro es si una lista es intercalada (o sea sus elementos están intercalados entre los del tipo A y los del tipo B). Vamos:

cosnt hayUnoDeCada = { (e1, e2) => (e1.esUnA() and e2.esUnB()) or (e1.esUnB() and e2.esUnA()) }

lista.size() <= 1 or (1..lista.size() - 1).all({ n => hayUnoDeCada.apply(lista[n], lista[n-1]))

Listo, soy un hombre feliz.

Obsérvese que evito responder a los argumentos de Fer, con varios estoy en desacuerdo pero así es la vida.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/uqbar-project/wollok/issues/1768?email_source=notifications&email_token=ABDLKOOIAAZPQ3GZ72OR7HTQLQGMTA5CNFSM4ITICBBKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7T6FHI#issuecomment-535290525, or mute the thread https://github.com/notifications/unsubscribe-auth/ABDLKOJR44FJLAX65BVI7R3QLQGMTANCNFSM4ITICBBA .

fdodino commented 5 years ago

Je, anoche hablábamos con NicoS de tu poder de convencimiento, y la idea de los streams me parece una genialidad porque logras que satisfaga la idea del while sin sacrificar la didáctica: no creo que el alumne se sienta tentado y todos contentos. Sos un capo.

npasserini commented 5 years ago

Falta convencer a Lombardi :)

El jue., 26 de sep. de 2019 a la(s) 08:38, Fernando Dodino ( notifications@github.com) escribió:

Je, anoche hablábamos con NicoS de tu poder de convencimiento, y la idea de los streams me parece una genialidad porque logras que satisfaga la idea del while sin sacrificar la didáctica: no creo que el alumne se sienta tentado y todos contentos. Sos un capo.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/uqbar-project/wollok/issues/1768?email_source=notifications&email_token=ABDLKOKW7Q55ITLZ7SCVHBTQLSNLXA5CNFSM4ITICBBKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7VISRI#issuecomment-535464261, or mute the thread https://github.com/notifications/unsubscribe-auth/ABDLKOM5LRVUTPAEI3LESFDQLSNLXANCNFSM4ITICBBA .

lspigariol commented 5 years ago

Coincido en general con los argumentos tanto a favor de incluir el while como no incluirlo. Lo que aporto es una ponderación de cada cosa: El "costo" que implicaría corregir un mal uso del while en las clases de objetos me parece que es menor al lado de los potenciales "beneficios" de ampliar a otros ejemplos y usuarios.

Años atrás hubiera dicho otra cosa, pero luego de haber salido del planteo más esmoltoquero y haber aceptado el if como construcción del lenguaje, incorporar el while ya no me hace tanto ruido. Si bien no lo usaría en mis clases de objetos, no le quitaría la posibilidad a otro docente (o a mi yo del futuro) que encuentre una buena justificación para hacerlo.

independientemente de lo anterior, lo del stream esta bueno, pero para el publico que se imagina Carlos me parece que lo mas apropiado es el while a secas.

El jue., 26 sept. 2019 a las 10:59, Nico Passerini (< notifications@github.com>) escribió:

Falta convencer a Lombardi :)

El jue., 26 de sep. de 2019 a la(s) 08:38, Fernando Dodino ( notifications@github.com) escribió:

Je, anoche hablábamos con NicoS de tu poder de convencimiento, y la idea de los streams me parece una genialidad porque logras que satisfaga la idea del while sin sacrificar la didáctica: no creo que el alumne se sienta tentado y todos contentos. Sos un capo.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub < https://github.com/uqbar-project/wollok/issues/1768?email_source=notifications&email_token=ABDLKOKW7Q55ITLZ7SCVHBTQLSNLXA5CNFSM4ITICBBKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7VISRI#issuecomment-535464261 , or mute the thread < https://github.com/notifications/unsubscribe-auth/ABDLKOM5LRVUTPAEI3LESFDQLSNLXANCNFSM4ITICBBA

.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/uqbar-project/wollok/issues/1768?email_source=notifications&email_token=ACZRXG7E2YXJ3O3KWC5UNBDQLS53ZA5CNFSM4ITICBBKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7VU57Y#issuecomment-535514879, or mute the thread https://github.com/notifications/unsubscribe-auth/ACZRXG46LU7NMA43ZDLMRDDQLS53ZANCNFSM4ITICBBA .

fdodino commented 4 years ago

Dejo el link a una solución implementada por Javi hace unos años, hay que seguirla (es una PoC). Otra variante es ésta pero a mí no me convence, es un while como estructura de control como el if. La implementación es más completa, y se nota todos los efectos que trae: hay que actualizar el formatter, revisar el validador, trae un nuevo nodo posible en el AST.

fdodino commented 4 years ago

Siempre es útil pispear cómo es en Smalltak