¿Hay alguna razón por la cual el primer elemento de una matriz Zsh está indexado por 1 en lugar de 0?

27

Desde mi experiencia con los lenguajes modernos de programación y scripting, creo que la mayoría de los programadores están acostumbrados a referirse al primer elemento de una matriz por 0 como índice.
¿Hay alguna ventaja sustancial en el uso de 1 ?

Estoy seguro de que he oído hablar de más lenguajes distintos de Zsh que se comportan de manera similar con las matrices; está bien para mí, ya que es igualmente conveniente.
Sin embargo, como los lenguajes de script de shell lanzados anteriormente y ampliamente utilizados, como ksh y bash, todos usan 0, ¿por qué alguien elegiría alterar este "estándar" común?

Mi respuesta inmediata a mi pregunta sería "por supuesto que no";
entonces, la única explicación que se me ocurre con respecto a esta "característica exclusiva" de los shells sería " simplemente hicieron esto para mostrar un poco más su cool shell ".

Sin embargo, no sé mucho sobre Zsh o su historia, y existe una gran posibilidad de que mi teoría trivial sobre esto no tenga ningún sentido.

¿Hay alguna explicación para esto? ¿O es solo por gusto personal?

deekin
fuente
55
Algunas investigaciones históricas (¿o reflexiones obscenas?) Sobre el tema de 0 versus 1: exple.tive.org/blarg/2013/10/22/citation-needed
thrig
Por razones históricas, probablemente proviene de csh, que también usó indexación de matriz basada en uno.
Cuonglm
3
hoy en día, sh es un lenguaje estándar (no una implementación) que tiene diferentes intérpretes posibles. Algunos de esos intérpretes para el lenguaje sh como bash, ksh y yash admiten matrices como extensión, pero no son parte del lenguaje como gcc, un compilador para el lenguaje C estándar admite extensiones sobre el lenguaje C estándar. Y al igual que para C, no existe una implementación "oficial" de un intérprete "sh".
Stéphane Chazelas
1
Relacionado - comentarios en esta respuesta PPCG
Trauma digital
44
Quizás un poco fuera de tema, pero relevante. Los romanos usaban el conteo inclusivo, mirando desde uno en lugar de cero. Pasado mañana, para nosotros "dos días por delante", era para ellos "tres días por delante". Hoy contaban como uno, no como cero. Como consecuencia, cuando sus astrónomos egipcios recomendaron un día bisiesto cada cuatro años, los romanos lo introdujeron cada tercer año, comenzando en el año 45 a. C. Se tardó hasta 12 BCE para que se corrigiera el error.
Harry Weston el

Respuestas:

32
  • Prácticamente todas las matrices de shell (Bourne, csh, tcsh, fish, rc, es, yash) comienzan en 1. ksh es la única excepción que conozco (bash acaba de copiar ksh).
  • Idiomas más interpretados en el momento (principios de los 90): awk, tclal menos, y normalmente se utilizan herramientas de la concha ( cut -f1-3, head -n 3, sort -k1,3, cal 1 2015, comm -1) comienzan en 1. sed, ed, vinúmeros de sus líneas de 1 ...
  • zsh toma lo mejor del shell Bourne y csh. La matriz de shell Bourne $@comienza en 1. zsh es coherente con su manejo de $@(como en Bourne) o $argv(como en csh). Vea cuán confuso es en kshdonde ${@:0:1}no le da el primer parámetro posicional, por ejemplo.
  • Un shell es una herramienta de usuario antes de ser un lenguaje de programación. Tiene sentido que la mayoría de los usuarios tengan el primer elemento $a[1]. También significa que el número de elementos es el mismo que el último índice (en zsh como en la mayoría de los otros shells, excepto ksh, los arrays no son escasos).
  • a[1]porque el primer elemento es consistente con a[-1]el último.

Entonces, en mi opinión, la pregunta debería ser: ¿qué se le ocurrió a David Korn para que sus matrices comenzaran en 0?

Stéphane Chazelas
fuente
77
Es un error en los lenguajes humanos que la numeración está basada en uno, y una notable casualidad de que la mayoría de los lenguajes de programación lograron mantener ese legado fuera de su diseño. Es aún más triste que, después de que la indexación basada en cero se estableció virtualmente como el estándar, muchos lenguajes "orientados al usuario" lo hicieron al revés, tratando de ser "más simples" al usar la indexación incorrecta basada en uno nuevamente. - Dicho esto: la mejor manera de evitar la confusión de indexación es, por supuesto, evitar los índices numéricos por completo.
Leftaroundabout
Lectura aquí: "Cuando se trata de una secuencia de longitud N, cuyos elementos deseamos distinguir por subíndice, ... a) produce, al comenzar con el subíndice 1, el rango de subíndice 1 ≤ i <N + 1; comenzando con 0, sin embargo, da el rango más agradable 0 ≤ i <N . " . No sé si TROLL o STUPID, pero puede usar "1 ≤ i ≤ N" para los subíndices que comienzan con 1 en las matrices. No es necesario poner ese +1 al final de la exploración de la matriz, y ninguno de los puntos de vista demuestra que los índices iniciales con 1 o 0 son mejores.
1
Puede justificar que se agregó 0 DESPUÉS del conocimiento humano, y que de alguna manera arruinó las cosas esa vez. theguardian.com/notesandqueries/query/0,5753,-1358,00.html - Nuevamente, solo es una cuestión de punto de vista :)
3
Bourne shell array $ @ comienza en 0 (no 1) $ 0 es el nombre del programa que está ejecutando. deberías corregir tu tercer punto
Edward Torvalds
2
@edwardtorvalds, No, $0no es un parámetro posicional. No es parte de $@. "$@"es "$1" "$2" .... Cuando se trata de funciones, en muchos shells, verá que "$@"son los argumentos de la función, mientras se $0mantiene la ruta del script (o shell argv [0] cuando no se ejecuta un script)
Stéphane Chazelas
7

Creo que la respuesta más plausible a esto es la matriz inversa incorporada de zsh

Si tiene una matriz con 4 elementos, digamos myvar=(1 2 3 4)y desea acceder al cuarto elemento print $myvar[4], ¿no?

Sin embargo, si desea crear un bucle que enumere los elementos dentro de esta matriz al revés, es solo cuestión de usar índices negativos:

print $myvar[-1]   # will print 4
print $myvar[-2]   # will print 3
print $myvar[-3]   # will print 2
print $myvar[-4]   # will print 1

Esto debería explicar, ya que a partir de cero, no alcanzará uno de esos elementos ya que no existe -0.

La segunda razón detrás de esto es probablemente el código C relacionado con las variables en zsh que está usando into double intpara definir índices de matriz, y dado que usa el Complemento de dos para representar números negativos, no hay forma de representar -0( Firmado cero ), como puede hacer en flotante variables puntuales.

Si realmente está acostumbrado a los índices que comienzan en 0, le sugiero que use la KSH_ARRAYSopción para solucionar esto.

Y tomando el gancho del comentario de @cuonglm, las cshcaracterísticas implementadas zshse explican aquí . Parece que no es una razón histórica, sino una forma de proporcionar un ambiente de trabajo confortable para quienes están acostumbrados acsh


fuente
3
Entonces, esto debería hacer que acceda al primer y último elemento de la matriz al mismo tiempo, rompiendo toda la lógica de escanear una matriz;) Incluso podría crear un agujero negro. LOL
3
para matrices indexadas a 0, reemplace -con ~.
mikeserv
1
@mfxx: estaba hablando bash. Creo que maneja los índices negativos para los elementos establecidos como el azúcar de sintaxis, pero no lo hace de otra manera. No puedo recordar desde mi punto de vista, la gente debería crear un directorio y usar archivos para lo que sea que llenen en todo ese estado de shell. puede indexar esos elementos de la forma que desee.
mikeserv
1
~Es la inversión binaria. ~0es -1. (todos los bits se voltearon, se basa en cómo los números negativos generalmente se representan en forma de bits). En una matriz no establecida o una matriz con solo un elemento de índice 0, un [0], un [-0], un [-1] y un [~ 0] le darán lo mismo en una matriz tipo ksh.
Stéphane Chazelas
1
@ StéphaneChazelas: sí, creo recordar haber hecho esto ~cuando -indexno funcionó. Supongo que probablemente todo lo que hice fue ~-index. sí. Eso suena bien. ¡sí! y, por supuesto, eso también funciona para elementos no definidos. así que supongo que el comentario anterior debería ser: para matrices indexadas 0 agregar ~ . Supongo que solo manejó la parte -1 más fácil tal vez. no se. no está saltando a la vanguardia de mi memoria en este momento ...
mikeserv