Estoy planeando escribir un GolfScript mejorado para programas aún más cortos que pueden hacer más cosas. Esto no es un desafío; Es una solicitud de retroalimentación y consejos sobre lo que debo hacer. (ver etiquetas)
No estoy seguro de si esto debería ser Community Wiki. Si crees que sí, solo marca un moderador para convertirlo :)
Este lenguaje será muy similar a GolfScript. Todavía está escrito en Ruby. Sin embargo, tiene algunas diferencias:
- Utilizándolo
`
como delimitador de cadena, porque es un carácter poco común, por lo que se necesitará menos escape. (Otro personaje puede reemplazar su función, como#
(más sobre eso más adelante)).\`
para escapar de un backtick,\\
para escapar de una barra diagonal inversa, y no hay otras secuencias de escape. Si necesita una nueva línea, simplemente pegue una nueva línea literal real en la cadena. - Usando Ruby's
Rational
s para punto flotante de precisión arbitraria, uno de los principales defectos de GolfScript. - La capacidad de convertir tipos a otros tipos. Por ejemplo, puede convertir un bloque en una cadena.
- Expresiones regulares. Probablemente creado con
"..."
. Los operadores también estarán sobrecargados por ellos. Por ejemplo,"\W"~{`Invalid: non-word character`}{`OK`}if
. Se ejecutará automáticamente cuando se empuje desde una variable, como bloques. - Objetos de archivo y fecha, para hacer más cosas que eran imposibles en GolfScript. Estos no tendrán literales, pero tendrán funciones para inicializarlos, como
`file.txt`fl
(el nombre de la función de creación de archivos puede cambiar). - Hashes tal vez, pero no estoy seguro de eso. ¿Debería?
- Funciones de ayuda para hacer aún más. Por ejemplo,
`http://example.com`net
para el acceso a la red (nuevamente, senet
puede cambiar el nombre del operador).rb
ejecutar una cadena como código Ruby. Habrá muchos más de estos; Sugerencias bienvenidas. - No hay comentarios, por lo que
#
puede usarse para otra cosa. Si quieres un comentario,`comment here`;
funcionará bien. (Tal vez#
pueda reemplazar`
la función de) - Se reescribirá por completo de manera que sea mucho más fácil agregar funciones. Básicamente, el código será más legible. (¿Has visto la fuente de GolfScript?
:/
) - Estará en Github para que se pueda trabajar en colaboración. Lo licenciaré bajo MIT o algo así.
- No hay una nueva línea final, por lo que las quines truculentas funcionan: P
Y los estoy diferenciando porque creo que son los cambios más drásticos y útiles (excepto quizás agregar punto flotante):
- Tendrá muchas funciones de Ruby integradas. Por ejemplo,
shuffle
(que puede abreviarse comosf
) (anteriormente tomaba 9 caracteres ),tr
(anteriormente 14 caracteres ),sample
(sm
, previamente.,rand=
),flatten
(fl
, anteriormente ???), etc. - Será aplastado, como Rebmu. Por ejemplo, ahora puede hacerlo
~:a0<{0a-}aIF
(usando un nombre de variable de letra) en lugar de~:$0<{0$-}$if
(sobrescribiendo la función de clasificación). (ejemplo de aquí ). Tenga en cuenta que de esta manera, no distingue entre mayúsculas y minúsculas, y no se permiten números en los nombres de variables. Esto está bien en mi opinión ya que es un lenguaje de golf: P - Tendrá depuración. Agregaré la capacidad de proporcionar un indicador que especifique delimitadores de matriz, delimitadores de elementos, etc., salida de número (racional, flotante o int?), Siguiendo las instrucciones de una en una, tokenizando y generando cada token en lugar de ejecutar el programa, etc.
Entonces, mi pregunta es: ¿qué hay para mejorar? ¿Qué crees que debería agregar?
¿Alguna otra idea para esto, antes de comenzar a codificarlo?
code-golf
tips
golfscript
Pomo de la puerta
fuente
fuente
Respuestas:
E / S flexible
Golfscript no se puede utilizar actualmente para programas interactivos. Propongo que se agreguen algunas funciones para la entrada explícita (es decir
readline
,getchar
y amigos). El intérprete debería ver si el programa los usa antes de ejecutarlo.Si el programa no llama a ninguna función de entrada, el intérprete debe actuar como lo hace normalmente Golfscript.
No esperaría que el intérprete detecte las funciones de entrada en el código evaluado generado en tiempo de ejecución, pero si de alguna manera puede hacer eso, felicitaciones.
fuente
Incorporaciones más cortas
Alias de un solo carácter para todos los comandos integrados que no los tienen. Usaría
base
mucho más si fuera justoB
.fuente
b
como nombre de variable? Todavía; buena idea; solo recuerda no usar ese nombre si vas a usar la función, y si no estás usando la función, entonces no te afecta en absoluto.^
o$
) como nombres de variables. No empeora ese problema. Además, sugerí alias para permitir la compatibilidad con versiones anteriores, por lo que solo tendría que usar el nombre más largo si hubiera asignado algo más al alias más corto.Z
parazip
también sería muy útil.#include
y"#{IO.read'lib'}"~
es demasiado largo).mylang -Llibname somefile.ext
.Div-mod combinado
Este es un poco más nicho que algunas de las sugerencias, pero cuando trabajo en programas de teoría de números, frecuentemente me encuentro con ganas de una operación que saca dos enteros
a
yb
de la pila y empujaa/b
ya%b
. (En la actualidad esto es1$1$/@@%
).fuente
dvm
para DiV-Mod. Gracias por todas las ideas :-) +1Números
Cambie el lexer de modo que el 0 inicial no forme parte de un número:
También los números negativos deben escribirse con
_
:fuente
0 100-
100 negativo. +1~
. Por ejemplo, -1 es0~
. Esto alarga un pequeño número de números en un carácter, pero elimina la necesidad moderadamente frecuente de espacios en blanco después-
.{0\-}:~;
(~
un número negativo) y usarlonot
para bit a bit (comoand or xor
)?Acceso a toda la pila.
GolfScript es un lenguaje basado en la pila, pero el acceso a todos menos los tres elementos principales de la pila se limita
<integer>$
a copiar el enésimo elemento. Sería útil tener algo como elroll
comando PostScript para que sea más fácil trabajar con más de tres variables "en vivo".Idealmente, habría versiones de un argumento y de dos argumentos, pero si no hay suficientes nombres, entonces el argumento de un argumento debería tener preferencia por uno de un carácter.
El de un argumento solo toma el número de elementos para rodar. Por ejemplo
1 roll
, no hace nada;2 roll
es equivalente a\
;3 roll
es equivalente a@
;4 roll
y para números más altos no tiene un equivalente existente; lo más cercano posible es algo así como(y eso ni siquiera maneja números no enteros en ciertas posiciones en la pila, o activos
[
, y casi con seguridad también se rompe dentro de los bucles).El de dos argumentos también toma una cantidad para rodar;
a b roll2
es equivalente a{a roll}b*
.fuente
rotate
. Debería editar esto en la respuesta CW.roll
solo gira la matriz, ¿verdad?CJam
He implementado "un GolfScript mejorado" y se llama CJam - http://sf.net/p/cjam
Ahora en la segunda versión (versión 0.6) ya tiene muchas, si no la mayoría de las características discutidas aquí. Trataré de enumerarlos:
`
como delimitador de cadena: no, pero usa cadenas entre comillas dobles con\
escapes mínimos ( solo escapes\
y"
)`http://example.com`net
-"example.com"g
#
usado para otra cosa,"comments like this";
mr
er
_,mr=
depuración: solo trazas de pila y
ed
operador para mostrar la pilaE / S flexible: sí, pero solo entrada explícita
b
= base,z
= zip-
- sí, pero no con_
;1 2-3
->1 2 -3
;1 2m3
->-1 3
t
md
m*
et
ea
e<
,e>
z
(GolfScript tieneabs
, no falta):+
,:*
c
(se convierte en un carácter, no en una cadena){}/
:
eso consume lo que está almacenado - no>=
,<=
- no, uso<!
,>!
1$1$
CJam tiene muchas más funciones, consulte https://sourceforge.net/p/cjam/wiki/Operators/
fuente
Cambiar el lexer
El lexer de GolfScript trata un identificador Ruby (cualquier cosa que coincida con la expresión regular
[_a-zA-Z][_a-zA-Z0-9]*
) como un token único. Si en cambio, se trata[a-zA-Z]+
como un token que se liberaría_
para ser incorporado y permitiría que una variable alfa fuera seguida de un entero literal sin separar espacios en blanco.fuente
[a-z]+|[A-Z]+
, para el mushing, por lo que subrayar es gratis. ¡Sin embargo, esta es una idea interesante y muy única! +1Alias Unicode
Los comandos de varios caracteres pueden tener alias unicode. Esto ahorraría en la puntuación cuando la puntuación se cuenta en caracteres y no en bytes.
fuente
Tipo estable
La
$
construcción en bloques debe realizar una clasificación estable.fuente
Operador de conjunto de matrices
¿Algún incorporado que podamos poner a disposición para eso?
fuente
Identificadores de un solo carácter
No es como si una solución de código de golf tuviera demasiadas variables. Y ahorraría en espacios.
fuente
% como incorporado para el producto
fuente
Soporte de expresiones regulares
La falta de soporte de expresiones regulares siempre me ha parecido extraño en un lenguaje diseñado para jugar al golf. Sería genial tener
<string> <string> <string> y
(aliastr
, usando el alias one-char de Perl para ello)<string> <string> <string> s
(sustituir)<string> <string> <block> s
(sustituir con devolución de llamada)<string> <string> m
(partido)fuente
Construido para la fecha / hora actual
Actualmente es muy peculiar obtener fecha / hora usando evaluaciones de Ruby.
fuente
Los complementos Make |, & y ^ hacen algo útil en bloques
Por ejemplo,
<array/string> <block> |
se puede usar como función de índice¿Alguna idea para
<array/string> <block> &
o<array/string> <block> ^
?fuente
array block =
ahora?"0<" {0<} =
.array block =
para "seleccionar por predicado",
.Una forma de convertir los símbolos nuevamente en bloques de código
Actualmente, podemos vincular bloques de código a símbolos con
:
, pero no hay forma de revertir el proceso: la ejecución de un símbolo vinculado a un bloque de código solo ejecuta el bloque.Puedo ver un par de formas de implementar esto:
agregar nueva sintaxis, por ejemplo,
#foo
para empujar el valor defoo
a la pila, incluso si es un bloque de código, oagregue un operador para expandir cada símbolo en un bloque de código, de modo que (utilizando
_
como el nuevo operador), por ejemplo{2*}:dbl; {dbl dbl}_
, produciría{2* 2*}
.Puedo ver ventajas para ambos métodos. El último podría sustituir al primero, a costa de dos caracteres adicionales (en
{foo}_
lugar de#foo
), pero puedo ver algunas aplicaciones potenciales para la sintaxis anterior donde esos dos caracteres serían prohibitivos (por ejemplo, usar enarray #func %
lugar dearray {func} %
).Mientras tanto, la sintaxis anterior podría usarse para reemplazar la segunda si hubiera una forma conveniente de iterar sobre los tokens en un bloque de código (que de todos modos podría ser útil por sí solo).
En cualquier caso, propondría que los símbolos expandibles que están vinculados a las funciones integradas nativas (es decir, implementadas en el código Ruby) devuelvan algún tipo de código auxiliar que se pueda invocar para obtener la funcionalidad de la función integrada, aunque sea imposible o simplemente es poco probable que se anule. Por ejemplo
#$
(o{$}_
) podría regresar{builtin_dollar}
, por ejemplo , dondebuiltin_dollar
contendría la implementación real de la función$
incorporada (y /#builtin_dollar
o{builtin_dollar}_
simplemente debería regresar{builtin_dollar}
).Esto permitiría redefinir las incorporaciones sin perder el acceso a su funcionalidad (vea mi sugerencia anterior ), de modo que si, por alguna razón, quisiera cambiar los significados de
$
y@
, simplemente podría hacer#$ #@ :$; :@;
(o{$}_ {@}_ :$; :@;
).fuente
_
debe hacer el operador si el bloque de código contiene asignaciones variables. Lo obvio sería dejar:symbol
intactos los tokens y expandir cualquier otra cosa, pero esto provocaría la_
ruptura de cualquier código utilizando variables locales. Sin embargo, hacer que no rompa ese código puede ser prácticamente complicado.[[1] [2] [3]] _ -> [1 2 3]
.2:A;{1:A;A}_
?{1:A;2}
(o, para ser técnicos,{1:A builtin_semicolon 2}
si se incluye la función de expansión incorporada). Si se incluye algún tipo de característica de "exclusión de variables locales", es probable que se evalúe como justo{1:A;A}
.{builtin_1 :A builtin_semicolon 2}
.Preset variable con argumentos de línea de comando
Desafortunadamente, no queda ningún personaje sin asignar, pero ¿tal vez podamos usarlo
A
para eso?fuente
_
está disponible. Tal vez eso? De todos modos, sí, golfscript necesita una manera de tomar argumentos de línea de cmd +1Funciones nativas de Ruby que debería implementar
Esto es Wiki de la comunidad; ¡siéntase libre de editar y agregar las funciones que cree que debería implementar!
Formato: "
nativeFunctionName
(nameInMyLanguage
)"shuffle
(sf
)tr
(tr
)sample
(sm
)fuente
¡Tome características de APL y HQ9 + también!
fuente
Separando claramente los empotrados
por ejemplo, mayúsculas: incorporados; haciendo B para la base factible
fuente
{-}:+
.Variables locales / cierres
Una cosa que realmente extraño en GolfScript es la capacidad de cambiar temporalmente el valor de un símbolo .
En particular, actualmente no hay forma de anular temporalmente el significado de un "primitivo" integrado: una vez que, por ejemplo, redefinir
$
, nunca volverá a ordenar nada en ese programa. (Bueno, no sin escribir su propia implementación de clasificación, al menos). Sería realmente bueno poder decir, por ejemplo, que en este bloque de código$
significa algo más, pero aún así mantener el significado normal en otro lugar.En relación con lo anterior, sería bueno vincular símbolos en un bloque de código a su valor actual . Claro, puedo escribir, decir,
{$-1%}:rsort
y ser capaz de usarrsort
para ordenar e invertir una matriz, pero eso funciona solo mientras la definición de$
(-1
oo%
) no cambie, ya que mirsort
función todavía está llamando al símbolo global$
. Sería bueno poder decir "dejar dersort
hacer lo$-1%
que hace actualmente, incluso si esos símbolos se redefinen más tarde".En particular, la biblioteca estándar podría usar este tipo de enlace. Es sorprendente darse cuenta de que, por ejemplo, cambiar los
n
cambios en el comportamiento deputs
, o que redefinir!
completamente arruinaxor
. (Por otra parte, se debe tener precaución aquí, ya que, en particular, la capacidad de cambiar el comportamiento deputs
resulta ser la única forma de evitar imprimir una nueva línea final en la versión actual de GS).Editar: Ser capaz de convertir los símbolos nuevamente en bloques de código contribuiría en gran medida a implementar esta funcionalidad. En particular, la
{foo}_
sintaxis sugerida en esa respuesta realizaría efectivamente un nivel de enlace estático al expandir todos los símbolos en un bloque de código. Combina eso con un combinador de punto fijo para una unión estática profunda, y Bob es tu tío ...fuente
rsort
lo$-1%
que hace actualmente, incluso si esos símbolos se redefinen más tarde" ¿Entonces Emmental?Más funciones incorporadas
Haga que todas las variables de una letra az y AZ realicen alguna función útil genérica. Algunos complementos que faltan:
{+}*
cuando puedes hacerS
? ¡Tienes 52 funciones para trabajar aquí!x1 y1 x2 y2 --> abs(x2-x1)+abs(y2-y1)
ahora tendría que ser@-A@@-A+
siA
es un valor absoluto incorporado. Es cierto que esto solo surgió como pistas de mi publicación más reciente, pero siempre pensé que sería una buena manera de expandir golfscript: escriba qué sería útil tener funciones, recopilarlas y agregarlas como integradas.chr
).{}/
):
eso consume lo que está almacenado. Esto tendría que no quedar 'atascado' en los identificadores para ser útil.>=
,<=
1{\}{|}if
a algo como1?\?|if
1$
,2$
,3$
,4$
,5$
\.@.@\
fuente
Sería bueno si el valor escrito o calculado en la última línea de una función se devuelve automáticamente
fuente