¿Qué significa esta afirmación sobre C # y Java siendo la mitad de un lenguaje? [cerrado]

32

En el artículo: Por qué POCO , hay esta oración:

Maciej Sobczak lo dice bien: "Simplemente no me gusta cuando alguien me da la mitad del idioma y me dice que es para mi propia protección".

No entiendo lo que quiere decir, aunque C # es propiedad de Microsoft y Java es propiedad de Oracle , eso no significa que tengan la mitad del lenguaje, ¿verdad? No encontré ninguna evidencia para probar esa oración, y tengo mucha curiosidad por esto. Y aún más curioso sobre la parte 'por mi propia protección'.

123iamking
fuente
12
Lo interpreté como una crítica en contra de dejar que el programador haga cosas como asignar libremente y liberar memoria y ese tipo de "protección", pero no estoy seguro de si ese era el punto que estaba tratando de hacer.
Kayaman
15
No estoy seguro exactamente, porque el artículo del que está citando parece estar muerto, pero parece que está diciendo que Java y C # carecen de una serie de características más 'peligrosas' o controvertidas de C ++, como herencia múltiple o metaprogramación de plantillas.
GoatInTheMachine
3
Falta el contexto de la cita (el enlace es 404), por lo que lo único que obtendrá aquí es que las personas adivinan lo que probablemente quiso decir, o (más probablemente) las personas simplemente presentan su propia opinión. Si realmente desea conocer el contexto, es decir, lo que hay en la página perdida, la mejor opción es probablemente escribir al autor directamente, o tal vez tratar de encontrar la página perdida a través de la máquina de retroceso o similar.
JacquesB
2
La afirmación no tiene en cuenta que, incluso si puede manejarlo, no siempre desea exponer todos los aspectos posibles del desarrollo de software en un idioma. Claro que es posible que no tenga problemas para leer el código de administración de memoria, pero otros desarrolladores pueden no estar increíblemente entusiasmados por mantener ese código. Es similar al concepto de encapsulación. Además, C # le permite acceder a un montón de cosas a través de las directivas del compilador, los atributos especiales y la reflexión, aunque no es necesario usar esas cosas.
Mark Rogers
32
Por su propio bien, no preste atención a las personas que piensan que un lenguaje debe tener todas las características de C ++ para ser considerado "real" y "completo". No preste atención a las personas que piensan que la seguridad de tipo, la seguridad de la memoria y el comportamiento bien definido son "ruedas de entrenamiento". La corrección se está convirtiendo en el aspecto más importante del software en la mayoría de las industrias y las personas que se enorgullecen de no preocuparse por él pronto se volverán irrelevantes.
Theodoros Chatzigiannakis

Respuestas:

162

Sobczak no está hablando de propiedad corporativa. El "medio" lenguaje que le falta son todas esas cosas que no puedes hacer en muchos idiomas modernos, aunque como experto en informática bien educado sabe que podrían hacerse posibles: hereda de tantas clases como quieras. Asigne cualquier objeto a cualquier otro sin restricciones de tipo. Controle la asignación y la liberación de recursos manualmente en lugar de confiar en el compilador y el tiempo de ejecución para hacerlo por él.

La cuestión es que todas esas restricciones se pusieron en lenguajes de programación por una razón. Nosotros nos tenemos lenguas que permitieron todo esto. Con el tiempo descubrimos que el programador promedio está mejor con una cierta cantidad de restricciones y agarre manual, porque el potencial de cometer errores realmente malos es demasiado grande como para valer la potencia y la expresividad adicionales.

(Obviamente, esto a veces molesta a los programadores que realmente no necesitarían tanta mano. Sus quejas son a veces legítimas. Pero las personas son notoriamente malas para evaluar sus propias habilidades, y muchos que piensan que no necesitan las salvaguardas, en De hecho, los necesito mucho. No siempre es fácil distinguir entre los intelectos superiores reales que se sienten retenidos por las restricciones en los idiomas de alto nivel de los codificadores promedio que solo piensan que quejarse los hará parecer superiores, o que no saben mejor.)

Kilian Foth
fuente
67
Esta es mi respuesta goto .
Neil
71
También agregaría que no hay intelectos superiores que no necesiten las restricciones. Siempre es seguro asumir que todos se equivocan tarde o temprano. Y, por lo general, cuanto mayor es el intelecto, mayor es el error.
Neil
29
Hay un poco más de Java y C # que simplemente evitar que las personas se disparen en el pie. La administración de la memoria tomó una cantidad significativa de tiempo y esfuerzo del desarrollador antes de que apareciera la recolección de basura, por ejemplo, y es difícil hacer la administración manual de la memoria correctamente. La recolección de basura mejora la productividad del programador.
Robert Harvey
12
@RobertHarvey I 100% de acuerdo. Siendo un programador de C ++ desde hace mucho tiempo, era escéptico sobre la administración automática de memoria al pasar a C #. Una vez que supere eso, fue increíblemente liberador no tener que preocuparme por eso el 99% del tiempo. Liberó mi capacidad mental para pensar en otros problemas.
17 de 26
8
"Asignar cualquier objeto a cualquier otro sin restricciones de tipo" dynamic.
Arturo Torres Sánchez
34

Esto se explica bastante bien en la fuente original de la cita :

Decidí aprender más sobre C ++ y me convertí en su fiel apasionado; esto incluye mi interés en la forma en que es probable que evolucione este lenguaje. Además, he notado que se necesitan las técnicas más avanzadas y avanzadas para desarrollar bibliotecas útiles , no las aplicaciones reales. Teniendo esto en cuenta, he intentado escribir un par de mis propias bibliotecas para diferentes propósitos (ver mi página de descarga) y también trato de mirar por encima de los hombros de los desarrolladores de C ++ Boost (ver mi página de enlaces) para saber qué técnicas de alta gama son. Pasar tiempo en el desarrollo de bibliotecas que se supone que son genéricas y útiles al mismo tiempo es realmente exigente. Es por eso que los programadores nunca dejan de aprender.

[...]

Sigo jugando con C ++ y las técnicas para escribir software robusto. Para obtener una perspectiva más amplia en el área de software confiable, decidí invertir algo de tiempo en aprender Ada (y cosas relacionadas), que es un lenguaje que parece estar completamente abandonado por los negocios, aunque fue Ada quien realmente fue diseñado para ser complejo y confiable. sistemas. Tengo que admitir que aprender Ada fue realmente beneficioso para mí en el sentido de que me permitió echar un vistazo más fresco a mi trabajo y enfoques de desarrollo. Lo más importante es que algunas de las ideas del mundo Ada se pueden aplicar más o menos directamente a C ++ con buenos resultados en el área de robustez y corrección.

[...]

OK, lo olvidé Un día juré no aprender Java. Pero lo hice. Bueno, en la medida que me permite leer y escribir código de trabajo. He leído 'Thinking in Java' (disponible en línea, gratis) y 'Core Java' (no en línea, no gratis), también me invocaron indirectamente en algunos desarrollos de Java, y ... Bueno, no compro eso. Simplemente no me gusta cuando alguien me da la mitad del idioma y me dice que es para mi propia protección. Es como un martillo de papel, hecho ligero para que nadie se lastime al golpear el dedo ... Lo mismo se aplica a C #. Elijo el martillo de acero, para poder estar seguro de que cuando quiera jugar al macho, resistirá.
La pregunta es: ¿por qué tanta gente lo usa (Java, C #, etc.)? Hmmm ... Tal vez porque es muy bueno en algunos lugares. Pero hay situaciones en las que tanto el lenguaje como la biblioteca muestran que fueron diseñados más bien para applets (inicialmente) que para convertirse en utilidades para hacer todo. Simplemente promete demasiado y da muy poco en cuanto a la tecnología global. O como una solución que podría superar cualquier competencia.

Me gusta C ++ cuando se necesita la máxima potencia y la perspectiva más amplia. En lugares donde la expresividad de C ++ no es imprescindible, lenguajes como Tcl o Python parecen encajar perfectamente. No solo son abiertos con respecto a su evolución, sino que uno puede extenderlos e incorporarlos, dependiendo de las necesidades particulares. Veo muchas posibilidades soñando en esas tecnologías. También tiendo a abandonar C como lenguaje para la programación regular; esta parece ser una opción razonable solo como un objetivo para la generación de código, de lo contrario es demasiado propenso a errores. Hoy, Ada es mi segunda opción probable para proyectos más serios, siempre que tenga libre elección (que, desafortunadamente, no es el caso la mayor parte del tiempo).

En otras palabras, al autor de esa cita le gusta C ++, y no le gusta Java, y siente que a Java le falta la mitad de C ++. Y eso es todo lo que hay en esa cita.

Jörg W Mittag
fuente
18
Irónicamente, no le gusta C exactamente por la misma razón que le gusta C ++, es muy abierto, lo que permite mucha potencia y muchos errores.
GreySage
8
Considera que C ++ es más expresivo que Python
benxyzzy
12
@GreySage Eso también me llamó la atención ... ¿C es demasiado propenso a errores pero C # no te da suficiente poder? C está muy lejos de C ++? C # no tiene esquinas "inseguras" que le dan más control? Interesante combinación de opiniones, eso es seguro ...
WernerCD
10
@WernerCD realmente no puede decir acerca de C # inseguro, pero C y C ++ no tienen prácticamente nada en común, excepto que puede superar un fragmento de C90 básico en un fragmento de C ++ válido en el que el compilador no se atragantará.
Quentin
23

El artículo vinculado en el blog que publicaste se ha eliminado, por lo que es difícil estar seguro, pero como dice Kilian, es probable que cuando diga "la mitad del lenguaje" signifique que C # y Java se sienten como C ++ pero con mucho características y construcciones eliminadas para que sean más fáciles de usar o más seguras.

En 2006, cuando se escribió esto, cuando C # era relativamente joven y Java era inmaduro en muchos sentidos, y cuando el poder frente a la seguridad parecía una compensación donde solo se podía elegir uno, esta no era una posición totalmente irrazonable. .

En estos días esa posición no es razonable en absoluto. Solo pensando en los lenguajes convencionales, C # y Java han madurado enormemente, tomando prestadas características de otros lenguajes (particularmente funcionales) para promover la escritura de código seguro. También tenemos idiomas como Rust y Swift que se crean desde cero para hacer esto.

Si alguien menosprecia un idioma porque tiene tu mano, o dice que un idioma que es difícil de usar es algo bueno, tomaría cualquier cosa que dijera con un grano de sal. Solo tiene que mirar la vergonzosa cantidad de errores encontrados en el código del que dependemos todos los días, escritos por las mentes más brillantes de la industria, que se habrían evitado trivialmente mediante el uso de lenguajes 'seguros', para ver por qué.

GoatInTheMachine
fuente
66
Estoy de acuerdo con tu posición en el último párrafo. C ++ debería llamarse la "Fuente de las hazañas".
Caleb Mauer el
3
Además, para complementar su segundo párrafo, tanto Java como C # criticaron enormemente la sintaxis de C y C ++ por varias razones, incluyendo atraer a los desarrolladores de C / C ++ existentes con la promesa de una curva de aprendizaje más baja. A medida que maduran, han agregado sus propias características y tienen su propio sabor, pero en sus primeros días, era más fácil verlos como "C ++ pero menos potentes" ya que estaban posicionados más directamente como una alternativa a C ++.
Harrison Paine el
12

Mirando hacia atrás en los archivos , parece que esta cita fue de 2003 (a pesar del artículo que cita que es de 2006). En ese momento, C # estaba en la Versión 1. x , y carecía de muchas de sus características modernas :

Nuevas características

C # 2.0

  • Genéricos
  • Tipos parciales
  • Métodos anónimos
  • Iteradores
  • Tipos anulables
  • Getter / setter accesibilidad separada
  • Método de conversiones grupales (delegados)
  • Covarianza y contravarianza para delegados
  • Clases estáticas
  • Inferencia delegada

C # 3.0

  • Variables locales escritas implícitamente
  • Inicializadores de objetos y colecciones.
  • Propiedades implementadas automáticamente
  • Tipos anónimos
  • Métodos de extensión
  • Consultar expresiones
  • Expresión lambda
  • Árboles de expresión
  • Métodos parciales

C # 4.0

  • Enlace dinámico
  • Argumentos nombrados y opcionales
  • Co y contravarianza genéricas
  • Tipos de interoperabilidad integrados ("NoPIA")

C # 5.0

  • Métodos asincrónicos
  • Atributos de información del llamante

C # 6.0

  • Compilador como servicio (Roslyn)
  • Importación de miembros de tipo estático en el espacio de nombres
  • Filtros de excepción
  • Esperar en la captura / finalmente bloques
  • Inicializadores de propiedades automáticas
  • Valores predeterminados para propiedades solo de captador
  • Miembros con cuerpo de expresión
  • Propagador nulo (operador condicional nulo, verificación nula sucinta)
  • Interpolación de cuerdas
  • nombre del operador
  • Inicializador de diccionario

C # 7.0

  • Fuera de las variables
  • La coincidencia de patrones
  • Tuplas
  • Deconstruccion
  • Funciones locales
  • Separadores de dígitos
  • Literales binarios
  • Ref devoluciones y locales
  • Tipos de retorno asíncrono generalizado
  • Constructores y finalizadores con cuerpo de expresión
  • Getters y setters con cuerpo de expresión

C # 7.1

  • Asíncrono principal
  • Expresiones literales predeterminadas
  • Nombres de elementos de tupla inferidos

- "C Sharp" , Wikipedia (referencias y enlaces eliminados)

Probablemente sea más comprensible que C # pareciera medio lenguaje en ese contexto, ya que le faltaba mucho de lo que C # es hoy. ¡Es extraño pensar que ni siquiera tenía staticclases!

También faltaban más cosas, ya que C # estaba vinculado a .NET. Por ejemplo, WPF no estaba en ese entonces; todo fue WinForms.

Nat
fuente
Las clases estáticas pueden ser una mala elección de una característica que falta, ya que Java todavía no las tiene (el tipo C #). ¿A menos que esto sea un jab en Java?
user253751
1
@immibis No es una puñalada intencional en Java, pero, jeeze, ¿en serio? staticlas clases parecen una característica tan primitiva; Me imaginé que eran anteriores a las clases instanciadas.
Nat
2
Parece decir que los chorros de motor de pistón eran anteriores a los de motor a reacción; una "clase no instanciada" generalmente se denomina módulo o espacio de nombres , excepto en idiomas en los que todo el código debe estar dentro de una clase. (O llamando a una bicicleta como automóvil manual, o llamando a un teléfono fijo a un teléfono celular estacionario, o ...)
user253751
@Nat: tener clases estáticas es bueno, pero no tenerlas no cambia absolutamente nada. Puede hacer que todos los miembros de la clase sean estáticos, y todo lo que pierde son algunos tipos de errores del compilador si olvida que la clase estaba destinada a permanecer estática.
Jirka Hanika
@JirkaHanika Sí, de statictodos modos no soy un gran admirador de las clases. Honestamente, lo elegí como una característica para llamar porque parecía una parte realmente simple y primitiva de C #; No consideré que no estuvieran en Java.
Nat
3

Se quejaba de la falta de características del lenguaje que permiten un control detallado. Estas incluyen herramientas para

  • Hacer cumplir la inmutabilidad (como la constpalabra clave C ++ )
  • Controlar la vida útil y la propiedad del objeto
  • Controlar el uso de la memoria, el estilo de copia y asignación

Esto me recuerda una de mis críticas a Java:

todo es un puntero, pero los punteros no existen.

En los objetos C ++, los punteros y las referencias son tres conceptos distintos con una semántica clara. En Java solo tienes el pseudo-objeto-puntero. Al combinar esto y evitar la semántica de puntero verdadero, el modelo de objeto es menos claro.

En un programa C ++ bien definido, el programador puede esperar que las referencias sean válidas y no nulas. Debido a su modelo simplificado, Java no puede hacer las mismas garantías.

Los síntomas de este modelo menos claro incluyen el patrón de objeto nulo y yoda condicionales como 5.equals(potentiallyNullIntegerReference).

Wes Toleman
fuente
55
Esto es muy confuso. Los punteros (en el sentido lógico existen en Java) simplemente no puedes jugar con ellos. El objetivo de simplificar el modelo es permitir más garantías. La lógica de que puede asumir más sobre el código en un idioma tendrá menos restricciones es al revés. Más restricciones -> más garantías.
JimmyJames
1
@JimmyJames la frase significa que, aunque todas las clases de Java tienen una semántica de referencia implícita (yuck, por cierto), no puede tener un puntero real. Por ejemplo, no hay forma de obtener una "referencia" a una referencia. Esto paraliza el idioma en varios lugares y, en ocasiones, requiere soluciones alternativas (ver Map.mergecuándo simplemente desea actualizar un valor en un mapa).
Quentin
3
@JimmyJames: Algunos tipos de garantías útiles no se pueden ofrecer prácticamente sin imponer ciertas restricciones. Además, algunas optimizaciones útiles pueden requerir la imposición de algunas restricciones. Sin embargo, algunos lenguajes imponen restricciones inútiles que no ofrecen garantías útiles a los programadores y no deberían ser necesarios para realizar optimizaciones útiles. Algunas restricciones son simplemente malas.
supercat
3
@JimmyJames: Por otro lado, algunas de las restricciones más fundamentales de Java y el "modo seguro" C # les permiten ofrecer una garantía muy útil de que C ++ no puede: cualquier referencia (lo que en C ++ sería un puntero) que siempre existe observado para identificar un objeto en particular nunca será observado para identificar otra cosa .
supercat
3
¿Puedes proporcionar algunas citas para respaldar tu respuesta? Por ejemplo, AFAIK, la página no menciona const. Se hace mención "programación funcional", sin embargo, el lenguaje que utiliza como ejemplo es el esquema, que es no un lenguaje funcional puro (de hecho, los diseñadores del Esquema tienen cuidado de evitar el uso de la palabra "función" y hablan de " procedimientos "), por lo que parece que está utilizando la interpretación de" subrutinas de primera clase "de FP y no la de" transparencia referencial ".
Jörg W Mittag
1

Estoy de acuerdo con la respuesta de @Kilian pero agregaré algunos elementos.

1- Ejecutar contra una máquina virtual, no el sistema operativo

Como Java y C # se ejecutan a través de una máquina virtual, lógicamente se espera que no pueda hacer exactamente lo que quiere cuando está directamente en el sistema operativo, ya que es probable que corrompa algo en la máquina virtual. Además, con Java orientada como plataforma independiente, es aún más lógica.

2- Toneladas de aplicaciones no requieren que necesites ese tipo de cosas.

Hay toneladas de aplicaciones que realmente no necesitan que revises tantos detalles, pero si lo haces con un lenguaje que requiere que lo hagas, obtienes:

  • Más riesgos de tener errores debido a esas cosas innecesarias.
  • ¡Más costos de desarrollo, administración de memoria y pruebas toman tiempo y dinero!

3- Los idiomas se toman en función del costo / uso / riesgos de ponderación, como ... todo.

Con C ++ puedes hacer casi lo que quieras, esa es la elección de las personas de C ++. Sin embargo, cuanto más haya, más tendrá que manejar.

Entonces, cosas como la herencia múltiple no se abandonan solo por el hecho de que son peligrosas, sino que se abandonan porque su implementación tiene un costo (desarrollo, mantenimiento), todo por eso para una característica que rara vez se usa correctamente y puede generalmente se reescribirá de manera diferente.

Walfrat
fuente
El costo real de la herencia múltiple radica en el hecho de que no es posible mantener las dos garantías siguientes: (1) Si un miembro de la clase base Bse anula en la clase media M, entonces Bla versión de ese miembro solo será accesible a través de M' anulación de s; (2) dada cualquier referencia de tipo T, convertirla a cualquier supertipo y volver a Tproducirá una referencia equivalente al original. Ambas garantías son útiles, y apoyar la herencia múltiple requeriría renunciar al menos a una.
supercat
-1

Simplemente ponga todas las restricciones en lenguajes de alto nivel como C # y Java para proteger al programador. No existen tanto para proteger al programador de sí mismo, sino para proteger al programador de otros programadores.

¿Cuántas veces, como programadores, encontramos bibliotecas que eran francamente atroces en sus prácticas de codificación y diseño, pero que nos vimos obligados a usar por una razón u otra?

Estos programas suelen tener el sello distintivo del antiguo método de programación de procedimientos, con falta de encapsulación, muchas escrituras de memoria directa con poca o ninguna captura o manejo de errores. Los Segfaults persiguen en masa cuando intentan usarlos en cualquier proyecto a gran escala.

Ahí es donde los lenguajes como Java y C # son extremadamente útiles; no es que disfruten el hecho de que no nos dejan hacer todas las cosas buenas que hacen otros idiomas, es que disfrutamos la falta de dolores de cabeza que tenemos que soportar porque otros programadores abusarían de las cosas buenas que otros idiomas pueden hacer.

Las interfaces bien merecen cualquier tipo de compensación en términos de memoria o velocidad de ejecución en mi mente. ¡Espero que puedan ver que en cualquier tipo de aplicación de misión crítica de tiempo limitado, todas esas protecciones, el manejo adecuado de errores y, en general, estar seguros de que la memoria no se está agitando son cosas buenas!

Akumaburn
fuente
Esto no parece ofrecer nada sustancial sobre los puntos hechos y explicados en las 5 respuestas anteriores
mosquito
1
They exist not so much to protect the programmer from him/herself, but rather to protect the programmer from other programmers!o es para proteger a otros programadores del programador?
Tobia Tesan
@TobiaTesan Eso también :)
Akumaburn