lunes, agosto 20, 2007

Liaison

¿Es Pascal un lenguaje "verboso"? Depende de con cuál lenguaje lo comparemos, por supuesto, pero en términos generales, se puede decir que sí lo es, porque introduce mucha redundancia en determinadas construcciones sintácticas.
Eche un vistazo a la siguiente, por poner un simple ejemplo:
for i := 0 to 9 do
begin

WriteLn(i);
WriteLn(i * i);
end;
Parece un código tan claro que casi brilla, pero ¿adivina qué es lo que sobra? Le daré una pista: localice dos palabras reservadas consecutivas...
Y esto, ¿qué le parece?:
for i := 0 to 9
begin
WriteLn(i);
WriteLn(i * i);
end;
Efectivamente, he eliminado la palabra clave do por estar ubicada antes de un begin. En general, la penúltima sintaxis de Freya permite, como opción, eliminar los do y los then que van antes de instrucciones que empiecen con palabras reservadas. Esta medida es parte de un esfuerzo de limpieza de la sintaxis que se ha cargado también construcciones propias de Freya como for var, que antes indicaba que estaba teniendo lugar una inferencia de tipo para una variable local.
Una aclaración: dos palabras claves consecutivas no siempre indican redundancia. Sólo es así cuando la palabra clave sólo hace de "esqueleto", es decir, cuando su papel es evitar ambigüedades sintácticas.
¡Ah!, y si se pregunta por qué me preocupan ahora los lenguajes verbosos y la redundancia innecesaria: estoy harto de pagar precios astronómicos por la puñetera tinta de impresora, el tóner y el papel. Hay más razones, pero ésta es importante y me parece incluso suficiente...

Etiquetas: ,

17 Comments:

Blogger SHArQ said...

No, si ahora va a resultar que el diseño de la sintaxis de un lenguaje puede repercutir directamente en el medio ambiente. "Cosas veredes Mio Cid, que farán fablar las piedras."

Ya lo estoy viendo en la caja de Freya:

"The environment-friendly language"

xD

miércoles, agosto 22, 2007 10:06:00 a. m.  
Blogger Ian Marteens said...

¿Alguien conoce por aquí conoce a Cristina Narbona?

miércoles, agosto 22, 2007 7:37:00 p. m.  
Blogger Ian Marteens said...

Hablando en serio, la "verdadera" idea es lo que llamo "programación orientada a bloc de notas". La omisión de un DO o un THEN casi no se nota, relativamente, aunque tiene un precedente famoso: los puntos y comas opcionales de Eiffel. Estoy incluso pensando en que el analizador lexical pueda descomponer ELIF en ELSE IF (incluirlo en la gramática es un coñazo).

Pero hay ganancias en tiempo y espacio más grandes. Por ejemplo, las implementaciones basadas en expresiones:

  method+(c1, c2: Complex) =>
    new Complex(c1.r+c2.r,c1.i+c2.i);

Eso es más breve incluso que en C# (y ya no te digo Delphi o Chrome). El método devuelve algo, porque está implementado con una expresión, y el tipo de retorno se infiere cuando la expresión es un NEW.

O, por poner otro ejemplo, la equivalencia entre estas dos instrucciones:

  for i in nodo.izquierda yield i;

o simplemente:

  yield nodo.izquierda.

O las pruebas de rangos:

  i in 0..1

O la iteración sobre rangos "filtrados":

  for i in 0..500 : primo(i) do proc(i);

Al final, quien menos tiene que escribir, programa más rápido...

miércoles, agosto 22, 2007 8:46:00 p. m.  
Blogger Ian Marteens said...

... eso sí: el límite absoluto está en conservar la independencia de los cambios de líneas y los espacios en blanco. Sobrepasar esa línea es anatema, al menos para mí.

miércoles, agosto 22, 2007 8:48:00 p. m.  
Blogger José Hurtado Miranda said...

Las abreviaturas del CodeRush en Visual Studio son muy útiles para ahorrar tiempo al tirar líneas, lo mismo pasa cuando se usan los snippets.
Sinceramente no creo que para ser mas productivo al programar haya que entrar en la sintaxis, para eso ya se inventaron otras cosas.
Saludos.

miércoles, agosto 22, 2007 10:10:00 p. m.  
Blogger Ian Marteens said...

Intenta enseñar a programar con un lenguaje que te obliga a repetir cosas innecesariamentes (o a escribir public static void Main para escribir cualquier mierdecilla de programa), y ya te contaré.

jueves, agosto 23, 2007 1:51:00 a. m.  
Blogger Ian Marteens said...

... y hay otro beneficio importante: la escritura de libros. No se trata sólo de ahorrar papel, sino de poder escribir ejemplos consistentes. Por ejemplo, en un lenguaje como Delphi, con declaraciones repetidas en la implementación, es difícil escribir un tutorial para principiantes (aunque luego el Ctrl+Shift+C resuelva el asunto al programador). Por eso Freya permite tanto la implementación "inline" como el estilo separado como en Delphi (tiene la ventaja de simplificar la extracción manual de la "forma de contrato" de la clase).

De todos modos, mi idea es estimular, en lo posible, eso de la "programación orientada al bloc de notas". Da gusto ver ciertos y determinados programas en lenguajes funcionales. En cuatro líneas resuelven lo que otros en cuarenta.

Otra ironía de Pascal, más que de Delphi, es que se supone que la secuenciación de acciones ("ahora esto, luego esto otro") es fundamental para su paradigma de computación. Sin embargo, eso precisamente se penaliza en Pascal: como tengas que escribir dos acciones dentro de la rama THEN de un IF, ahí mismo tienes que teclear begin/end e indentar. ¿Por qué no usar, al menos en los casos más frecuentes, alguna forma sintáctica light para listas de instrucciones? Por ejemplo:

while j <= Max do
  Result[j] := true, j += i;

Aquí, no es tanto el ahorro en el begin/end... sino las posibilidades de ampliación de las expresiones lambda y los métodos anónimos. No es lo mismo crear un método anónimo con dos instrucciones en C#, que las encierra entre llaves, que hacerlo en un derivado de Pascal que te obliga a escribir casi un soneto con dedicatoria incluida.

El precio, por supuesto, es que el lenguaje se parezca cada vez menos a Pascal... pero eso es algo que me dejó de preocupar hace mucho. Para lenguaje tipo Delphi con mejoras, ya está Chrome. Apartarme de esa estrecha línea me deja más libertad para explorar.

jueves, agosto 23, 2007 2:11:00 a. m.  
Blogger SHArQ said...

Pero Ian...

¿Eso no sería un poco (digo yo, puedo equivocarme) como volver a la época de los lenguajes aquellos que parecía que competían por ver cuál era el más críptico? Vamos, que las instrucciones eran de poco más de dos letras y hacían que programar en assembler pareciese el paraíso...

No sé, el modelo Delphi (declaracion y despues implementación) yo creo que no está mal; se puede pensar que tienes todo "centralizado". Luego C# (o Java o C++ que son los lenguajes de los que "bebe") mejoran la legibilidad pero, y siempre en mi opinión, al desarrollador le cuesta más o menos lo mismo (en tiempo) teclear "begin..end" que "{..}", con la dificultad añadida del segundo modelo, que debes pulsar dos teclas (Alt+Gr y la segunda, que yo por lo menos soy incapaz de acertarla sin mirar al teclado).

Además un buen lenguaje debe tener su dosis justa de "verbosidad" porque si no, se hace muy difícil, por ejemplo, estudiar o revisar un listado fuente. Los errores leyendo sentencias complejas son exponencialmente más posibles cuanto más críptica es la sintaxis. Mira sino Perl: corchetes, paréntesis, llaves... Hay gente que se flipan con 'tripis', a mí dame una buena sentencia "map" xDD

Claro que comparado con Prolog hasta Perl es "verbose". ;-)


Saludos

jueves, agosto 23, 2007 12:11:00 p. m.  
Blogger Alfredo Novoa said...

Yo estoy de acuerdo en que el do de los bucles de Pascal no aporta absolutamente nada, pero hay veces en que usar dos palabras reservadas seguidas hace más agradable la lectura. Yo estoy de acuerdo con sharq. Algunos lenguajes funcionales hacen daño a la vista.

También me parece muy bien que no te preocupe alejarte de Pascal.

jueves, agosto 23, 2007 1:20:00 p. m.  
Blogger Ian Marteens said...

¿Eso no sería un poco (digo yo, puedo equivocarme) como volver a la época de los lenguajes aquellos que parecía que competían por ver cuál era el más críptico?

Puede que sí, que quien se equivoque en esto sea yo. Pero de momento tengo la impresión contraria. ¿Has visto ya "Joyride", es decir, Chrome 2.0? Compara:

method SetEventHandler;
begin
  var lNewCaption := 'Clicked!';
  Button1.Click += method(Sender: Object; ea: EventArgs); begin
    Button1.Text := lNewCaption
    MessageBox.Show('the button was clicked.');
  end;
end;

con lo mismo escrito en C#:

void SetEventHandler()
{
  var lNewCaption = "Clicked";
  button1.Click += delegate(object sender, EventArgs e)
  {
    button1.Text = lNewCaption;
    MessageBox.Show("the button was clicked.");
  }
}

La "carne" es la misma... pero en el ejemplo de Chrome hay demasiado "hueso".

Dos inglesas se encuentran en un mercado. Le pregunta la una a la otra:

- ¿Cómo está tu marido?
- ¿Comparado con qué?

jueves, agosto 23, 2007 4:03:00 p. m.  
Blogger Ian Marteens said...

pero hay veces en que usar dos palabras reservadas seguidas hace más agradable la lectura

:) Vale. Reescribe el ejemplo así:

for i := 0 to 9 begin
  WriteLn(i);
  WriteLn(i * i);
end;

El begin es el do en este caso. Sigue manteniendo la estructura sintáctica en "peine" de la que hablaba Meyer respecto a Eiffel.

Más peligroso es permitir la coma para separar asignaciones y llamadas a métodos... pero, o eso, o a escribir toca con los malditos métodos anónimos. Con la coma:

  Button1.Click += method(Sender: Object; ea: EventArgs);     Button1.Text := lNewCaption, MessageBox.Show('the button was clicked.');

... y el problema es que los "malditos" métodos anónimos son un verdadero avance: acercan el código al sitio donde se usa. La verdad es que me gustaría más otro tipo de "operador de secuencia", más gráfico (pero ya los mejores están pillados).

Por cierto, ¿habéis visto el operador : de Chrome, para tipos de referencia y anulables?


Mi "preocupación", en este caso concreto, es si el programador va a acordarse, mientras escribe, que puede saltarse el do. Pero no pasa nada si no lo hace: es sólo una opción.

. Yo estoy de acuerdo con sharq. Algunos lenguajes funcionales hacen daño a la vista.

También me parece muy bien que no te preocupe alejarte de Pascal.

jueves, agosto 23, 2007 4:18:00 p. m.  
Blogger Ian Marteens said...

Yo estoy de acuerdo con sharq. Algunos lenguajes funcionales hacen daño a la vista.

Hay varias razones: la extrañeza de las bibliotecas. Yo me pierdo cuando empiezan los "maps". La otra razón es que, desde el punto de vista del "refinamiento sucesivo", hay demasiada distancia para saltar de golpe entre el planteamiento y la respuesta. La programación imperativa deja más huellas del proceso de razonamiento.

También me parece muy bien que no te preocupe alejarte de Pascal.

Es que siendo objetivos, el nicho de "Delphi mejorado" ya lo llena Chrome. Pero eso era previsible. Al final, el principal beneficio de Freya pueden ser las herramientas generadas a partir del know-how desarrollado. O un segundo lenguaje, desarrollado from scratch.

jueves, agosto 23, 2007 4:23:00 p. m.  
Blogger Ian Marteens said...

Mierda de formato de comentarios de Blogger:

  Button1.Click += method(Sender: Object; ea: EventArgs);
    Button1.Text := lNewCaption, MessageBox.Show('the button was clicked.');

jueves, agosto 23, 2007 4:25:00 p. m.  
Blogger Ian Marteens said...

La idea es que method admita una instrucción a continuación, igual que lo hacen if, while y for. Un bloque begin, en definitiva, es sólo un tipo de instrucción. Si las instrucciones "básicas" pueden separarse con coma, el begin puede omitirse en muchos más casos.

Eso sí: ¿os habéis dado cuenta de que los ejemplos de Freya se indentan cada cuatro caracteres? Al menos el menda usaba dos caracteres de sangría con Delphi (igual que Borland).

jueves, agosto 23, 2007 4:28:00 p. m.  
Blogger SHArQ said...

Hmmm...

En el ejemplo del method tienes toda la razón, yo personalmente considero que utilizar diferentes caracteres como separador de instrucciones (aquí punto y coma, allí sólo una coma...) es un coñazo -o "peligroso" como tú dices- y si me apuras, hasta un fallo de diseño (sí, porque habría varios caracteres con varias funciones según el contexto que estuviesen situados: separar instrucciones, separar parámetros... desastroso). No señor, cada cosa en su lugar. Y además me "perdería" un poco, quizás me costase acostumbrarme a que esa orden que viene detrás del punto y coma ES el método, y no la instrucción a continuación de la de arriba... Creo que aunque se trate de un método anónimo (o "inline", "on-the-fly" o como se quiera), no deja de ser un simple bloque de código. Enciérralo pues en sus demarcadores, que pa eso están.

En cuanto a los ejemplos de código en Chrome 2 "Joyride" y C#, pues es un poco lo que te decía: la sintaxis C# mejora la legibilidad, y mucho... y quizás (sólo quizás) a la hora de escribir el código sea indiferente una sintaxis que otra, porque los IDEs más o menos "inteligentes" ya se encargan de poner los tags de comienzo y cierre ellos solitos. Lo cual podria dejar sin base argumental mi comentario acerca de la preferencia de la sintaxis Delphi... si ya no tienes que escribir pos usa el que mejor se lea después :P

Lo de la cantidad de caracteres en la indentación... yo creo que va por modas. Pero pensándolo un poco, quizás a los lenguajes excesivamente "verboses" le vaya mejor una mayor cantidad de caracteres indentados (=mayor legibilidad), y a los que trabajan con llaves, con ese par de espacios de indentación ya les bastaría (yo uso tres tanto en Delphi como en C#... me encanta cómo me desmonto yo mismo mis propias teorías xDD)

Que por cierto, no sé si llegaste a ver código escrito por alguien que tú y yo conocemos ;-) y éste ni modas ni *stias en sirope: directamente, indentación CERO.

jueves, agosto 23, 2007 5:27:00 p. m.  
Blogger Ian Marteens said...

Por hacer la prueba, ¿qué te parecería algo como esto?

while j <= Max do
    Result[j] := true -> j += i;

No es que el operador sea el perfecto, pero es para dar la idea de "esto ahora, y a continuación, esto otro". Recuerda que se trata más de un recurso para métodos anónimos, aunque se pueda usar en más lugares.

directamente, indentación CERO.

:) Por la parte que me toca, aunque nunca nadie me lo ha dicho, hay cierto libro que tiene un fragmento de código en la portada... que juro por Vishnu que no lo escribí ni indenté yo...

Luego, si me da tiempo, escribiré un post corto sobre una "pista" sobre LINQ, de la que me he dado cuenta precisamente experimentando con Freya. Es muy sencillo, pero creo que mucha gente lo pierde de vista con demasiada facilidad.

jueves, agosto 23, 2007 8:14:00 p. m.  
Blogger SHArQ said...

while j <= Max do
   Result[j] := true -> j += i;


hmmmm sigo sin verlo claro. No sé, veo "fea" la flechita esa (le tengo una aversión patológica a los operadores >> y << de C++, a ver si va a ser de eso)

Ahora yo:

while j <= Max do
   Result[j] := true; j += i;;


Se utiliza el separador estándar para las instrucciones, y se "enfatiza" el final con un separador doble. Por ejemplo. Y se me ocurre que también podria utilizarse para ese menester algun otro tipo de terminador como ;. (punto y coma + "punto final") o bien ;| (punto y coma + pipe, éste actuaría como de "pared", como "hasta aquí has llegao chaval"). Aunque de cara al "machaca" que le toque teclear código, esta última opción la veo menos "ergonómica". Y detallitos como ese pueden causar que el susodicho tenga la ocurrencia, en más de una ocasión, de acordarse del árbol genealógico del diseñador del lenguaje xD

Buenas noches! :)

viernes, agosto 24, 2007 1:34:00 a. m.  

Publicar un comentario

<< Home