java - Tienda de ultramarinos
logo Tienda de Ultramarinos
Etiquetas: java

Incremento y decremento

Hoy toca post para informáticos. Como bien sabréis, muchos lenguajes disponen de una forma abreviada de indicar incrementos y decrementos, que son ‘++‘ y ‘--‘. Esto, además de facilitar la vida a los programadores evitándoles escribir a=a+1, es también de utilidad para las optimizaciones que hace el compilador, puesto que en la mayoría de arquitecturas existen instrucciones de incremento y decremento que se ejecutan utilizando menos recursos que una suma convencional.

En algunos lenguajes, como en C y Java, se puede utilizar este operador delante y detrás de las variables, pero tiene un comportamiento distinto. Si el operador está delante, se hace primero la resta y se evalúa el resultado; mientras que si está detrás, primero se devuelve el valor, y después se realiza la resta.

Así, si b=10 y hacemos a=--b, a y b terminarán con valor 9, pero a=b-- terminará con a=10 y b=9.

Bien, recordado esto, en mis apuntes de compiladores se menciona como un código algo lioso a primera vista, la siguiente instrucción c=a---b--. A raíz de ello, he decidido pensar en  situaciones similares a ésta, que son:

c = --a---b;
c = --a-b--;
c = a-----b;
c = a---b--;
c = a---b;

Suponiendo que es ilegal --n--, y obviando la última (hay que acordar cómo se comporta) ¿Alguien se anima a hacer la traza? Es facilita, la hice ayer a mano en lugar de seguir estudiando :P.

Aunque todas salvo la última parezcan correctas y sin ambigüedades, curiosamente hay dos de ellas que ni C ni Java aceptan (con los compiladores GCC 2.8.1, Borlandc 3.0 y JDK 1.6). Son la primera y la tercera, y ocurre lo mismo si en lugar de ‘--‘ utilizamos ‘++‘. ¿Por qué? Pues imagino que por el tipo de análisis que hace el compilador.

Tal y como veo que se comporta (he hecho más pruebas aparte de esos 5 casos), cuando el analizador léxico lee el código carácter a carácter, siempre que encuentra dos ‘-‘ seguidos, los considera un único token ‘--‘ y así es como los envía al siguiente nivel.

Después, en el analizador sintáctico/semántico debe de existir algún tipo de precedencia asignada al operador ‘--‘ por encima de la resta y el opuesto, de modo que cuando se encuentra con --a, ó a--, hace directamente una reducción y pasa a considerar la expresión como una constante, a la que ya no tiene sentido volver a aplicar otro ‘--‘.

En el caso “especial” c=a---b, a mi juicio el único que es ambiguo y del que debería quejarse el compilador, se opta por aplicar el operador ‘--‘ a la variable a; siendo equivalente a ejecutar c=a-b y después a--.

También acepta correctamente c=-a--; // c = -a (y decrementar después a).

Otras asignaciones que dan error de compilación, y comentado a lo que debería corresponder:

c = ---a; //c = – (decremento de a)

c = --a--b; //c = (decremento de a) menos (-b)

c = a--b; // c = a menos (-b)

c = a----b; // c = a menos (-b) [y después decrementar a]

Por los errores que da el compilador, en el primer caso creo que intentar aplicar el operador ‘--‘ sobre ‘-‘, y en el tercer caso, evalua ‘a--‘, y después encuentra la b sin operadores entre ellos. En el segundo fallan dos cosas: primero aplica correctamente --a, pero al resultado no se le puede aplicar otra vez ‘--‘; el segundo fallo es que ha consumido el token ‘--‘ y se encuentra, de nuevo, con una b solitaria sin operadores entre la a. En el cuarto tenemos otros dos fallos similares al anterior.

¿Ocurrirá así en todos los compiladores de C, o habrán tenido esto en cuenta en algún caso? ¿O es algo definido directamente en el estándar? He echado un vistazo rápido al ANSI C buscando “decrement”, pero no he leído nada destacable.

IBM interesada en comprar Sun Microsystems

Parece ser que la semana pasada se filtraron noticias de una posible compra de Sun Microsystems por parte de IBM, dispuesta a pagar 6500 millones de dólares por ella. Esto habrá tenido que conmocionar a la blogosfera, pero yo me entero hoy por Mundo Geek.

Sun Microsystems es responable, entre otros muchos productos, del lenguaje de programación Java, el sistema operativo Solaris, y compró MySQL el año pasado. También desarrollaron durante los 80 su propia arquitectura de computador, el SPARC; están detrás de Open Office, una de las principales alternativas de software libre a la suite de Microsoft. También aportan soluciones hardware de almacenamiento en plan tocho y últimamente están ofreciendo servicios en torno al cloud-computing.

IBM no necesita presentación. La historia de la informática no tendría sentido sin el gigante azul, contando con infinidad de patentes en todos los campos imaginables. Gran parte de los protocolos, soluciones y sistemas que utiliza cualquier ordenador de hoy en día se gestaron en sus laboratorios. Como dato curioso, cuando se asignaros los diferentes dominios en los primeros tiempos de internet, se reservaron la mayoría para los diferentes países, pero alguno fue también concedido a IBM. En la actualidad es la segunda empresa de informática del mundo, detrás de HP.

A falta de más conocimiento sobre ambas empresas que el general, y sin ninguna posición al respecto, me he lanzado a leer el debate al respecto en Java Hispano. Al igual que lo visto en una rápida ojeada en Barrapunto, el flame principal está en el temor de que puedan cargarse NetBeans, el IDE para Java desarrollado por Sun, para favorecer a Eclipse, de origen en IBM.

Pese a todo, pueden llegar a leerse cosas interesantes y opiniones razonadas, sólo hay que saltarse las primeras respuestas escritas en el calor del momento. Hacia el final hay buenas reflexiones sobre las soluciones hardware y software que tienen en común, y que hacen dudar si en el futuro se mantendrían ambas. Esto mismo que es utilizado como una pega de la compra de IBM, es también utilizado como una baza a favor, contraargumentando a los que prefieren que sea Google quien compre Sun.

Google se ha erigido como un gigante bueno entre toda la comunidad virtual (y he de confesar que yo también lo miro con muy buenos ojos) pero tampoco creo que fuera el mejor comprador de Sun. Como bien argumentan algunos, el modelo de negocio de Google es completamente diferente, y no tiene la experiencia que posee IBM en la mayoría de asuntos que trata Sun. Además, Google sólo se hace con tecnologías en las que pueda incluir publicidad y hacer uso de su potente algoritmo de búsqueda. ¿Tendríamos que soportar AdSense mientras programamos? ¿Basarían los contenidos de los anuncios en los nombres de las clases y los métodos usados? Cuando utilicemos el patrón Singleton, nos mostrarán páginas de contactos; si detectan el patrón Observer, pondrán anuncios de binoculares. Así pues, creo que se le asegura un mejor futuro a todo lo desarrollado por Sun con una compra por parte de IBM, más afín a sus productos.

En otro orden de cosas, la noticia original del Wall Street Journal , asegura que Sun llevaba una temporada arrastrándose buscando un comprador; HP declinó la oferta, y Dell (la tercera compañía informática a nivel mundial) no hace declaraciones al respecto. Y parece razonable, viendo cómo han ido cayendo sus acciones desde los 25 dólares de noviembre de 2007, hasta los cuatro en que estaban antes de conocerse la oferta de IBM (tras lo que se han revalorizado un 65%) Y habían llegado a estar por debajo de los tres dólares; ahora mismo rondan los ocho.

Otra opinión al respecto, favorable esta vez, la dan en Between The Lines, donde argumentan que IBM estaría muy interesado para fortalecerse en el ámbito del hardware, especialmente almacenamiento, donde Sun parece bastante fuerte. Aquí por lo visto, el detonante lo ha puesto Cisco que, como apuntan en más lugares, había entrado recientemente al mercado de los servidores (que ahora mismo, con las redes evolucionando a pasos agigantados, parece ser la principal inversión por todas partes).

Java: Problemas de contrabarra

Para el Proyecto tengo que hacer unas llamadas a R, el programa de análisis estadísticos, desde Java. Uno de los comandos que le ordeno es que lea un fichero de texto CSV donde se encuentran las entradas y salidas. En R, simplemente:

basedatos<-read.table("/home/ender/iris.csv",sep=";",header=TRUE,dec=",")

Para lanzarlo desde Java, sería (JFileChooser explorador, String sep=”;”, String dec=”,”):

re.eval("basedatos<-read.table(\"" + explorador.getFile().getAbsolutePath() + "\",sep=\"" + sep + "\",header=TRUE,dec=\"" + dec + "\")");

He estado todo este tiempo programando desde Linux y no había tenido ningún problema, pero dado que Java es multiplataforma, me dediqué ayer a preparar el resto de programas (R y JRI, la librería que permite la comunicación mediante JNI desde Java) para poder usarlo desde Windows. Y el caso es que me daba error.

Imaginé en seguida que sería problema de las rutas y, efectivamente, R no acepta las direcciones con la contrabarra, tal y como se dan en Windows. Para solucionarlo, obviamente, no hay mas que cambiar todas las contrabarras por barras, para lo cual hay un comando que implementa todo String:

path = path.replaceAll("\\","/");

Recordemos que la contrabarra es utilizado como carácter de escape para caracteres que no tienen representación gráfica (intro, tabulado, etcétera) de modo que hay que “escaparla” poniendola dos veces. Pues no funciona. Por algún motivo Java no lo reconoce como String, sin embargo existe otro método para caracteres con el que funciona correctamente.

path = path.replace('\\','/'));

He hecho un par de pruebas y no sé qué miedo le tiene a las contrabarras como String, porque algo como:

String aux = "albaricoque/gemir/susurro/sociedad";
System.out.println(aux.replaceAll("/","."));
aux = "albaricoque\\gemir\\susurro\\sociedad";
System.out.println(aux);
System.out.println(aux.replaceAll("\\s","."));
System.out.println(aux.replace('\\',','));
System.out.println(aux.replaceAll("\\",","));

Devuelve por pantalla:

albaricoque.gemir.susurro.
albaricoque\gemir\susurro\sociedad
albaricoque\gemir\susurro\sociedad
albaricoque,gemir,susurro,sociedad
Exception in thread "main" java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
\
^

Aquí se ve que la barra como String es reconocida sin problemas, pero no la contrabarra, que de hecho lanza una expcepción. He pensado que al ser un carácter de control pueda no funcionar correctamente sólo, por lo que he probado que modifique las \s por puntos, pero no cambia nada.

Echando un vistazo en Google, en un foro dan una solución, pero no entiendo por qué hay que codificarlo así:
System.out.println(aux.replaceAll("\\\\","."));
albaricoque.gemir.susurro.sociedad

¡Cuatro barras para que encuentre una!

Delicioso manual de compresión de Java

man jar

java.util.Map

java.util.map